This commit is contained in:
qiaopengfei 2024-07-25 11:13:30 +08:00
parent 8fca5e55b3
commit 74bc0df089
18 changed files with 2589 additions and 1183 deletions

View File

@ -1,10 +1,10 @@
VITE_MODE = 'development' VITE_MODE = 'development'
VITE_APP_BASE_API = 'http://d1-api.erp.xtkj99.com:88' VITE_APP_BASE_API = 'https://122.228.26.226:12025'
# VITE_APP_BASE_API = 'https://pre-api.aiguoerp.com' # VITE_APP_BASE_API = 'https://pre-api.aiguoerp.com'
# VITE_APP_BASE_API = 'http://localhost:80' # VITE_APP_BASE_API = 'http://localhost:80'
VITE_APP_BASE_SITE = 'http://localhost:80' VITE_APP_BASE_SITE = 'http://localhost:80'
VITE_APP_BASE_URL = 'http://192.168.2.5:9986' VITE_APP_BASE_URL = 'http://d1-api.erp.xtkj99.com:88'

View File

@ -88,7 +88,7 @@ onMounted(() => {
overflow: hidden; overflow: hidden;
} }
.routeview { .routeview {
height: calc(100vh - 38px); height: calc(100vh - 40px);
overflow-y: auto; overflow-y: auto;
&::-webkit-scrollbar { &::-webkit-scrollbar {
display: none; display: none;

View File

@ -0,0 +1,41 @@
import request from '@axioshooks'
// 获取商品分类
export function getGoodsType(data) {
return request({
url: 'xy_openapi/publish/getGoodsType',
method: 'post',
data
})
}
//获取商品属性
export function getGoodsInfo(data) {
return request({
url: 'xy_openapi/publish/getGoodsInfo',
method: 'get',
data
})
}
//获取闲鱼店铺
export function getshopInfo(data) {
return request({
url: 'xy_openapi/publish/shop/info',
method: 'get',
data
})
}
//上传图片
export function uploadImage(data) {
return request({
url: 'xy_openapi/publish/uploadImage',
method: 'file',
data
})
}
//获取发货地
export function region(data) {
return request({
url: 'xy_openapi/region',
method: 'get',
data
})
}

View File

@ -16,10 +16,10 @@ export function login(data) {
}) })
} }
/*获取阿里云签名*/ /*获取阿里云签名*/
export function get_oss_sign_aliyun(data){ export function get_oss_sign_aliyun(data) {
return request({ return request({
url:'base_config/get_oss_sign_aliyun', url: 'base_config/get_oss_sign_aliyun',
method:'post', method: 'post',
data data
}) })
} }
@ -32,11 +32,11 @@ export function get_user_menu(token) {
}) })
} }
/*获取用户信息*/ /*获取用户信息*/
export function getInfo(token) { export function getInfo(data) {
return request({ return request({
url: 'menu/get_userinfo', url: 'auth/getUserInfo',
method: 'post', method: 'get',
params: { token } data
}) })
} }
/*判断是否绑定拍机堂账号*/ /*判断是否绑定拍机堂账号*/

View File

@ -1,74 +0,0 @@
import request from '@axioshooks';
/* 店铺列表*/
export function xy_shop_list(data) {
return request({
url: 'xy_shop/xy_shop_list',
method: 'post',
data
})
}
//获取授权地址
export function get_auth_address(data) {
return request({
url: 'xy_shop/get_auth_address',
method: 'post',
data
})
}
//授权完的确认是否授权成功
export function affirm_auth_success(data) {
return request({
url: 'xy_shop/affirm_auth_success',
method: 'post',
data
})
}
//创建账号
export function account_config_create(data) {
return request({
url: 'base_config/account_config_create',
method: 'post',
data
})
}
//创建账号新
export function xy_account_config_create(data) {
return request({
url: 'base_config/xy_account_config_create',
method: 'post',
data
})
}
//删除店铺
export function account_config_delete(data) {
return request({
url: 'base_config/account_config_delete',
method: 'post',
data
})
}
// 第三方账号配置编辑||店铺修改
export function account_config_edit(data) {
return request({
url: 'base_config/account_config_edit',
method: 'post',
data
})
}
//获取行政区id
export function get_division_id(data) {
return request({
url: 'xy_shop/get_division_id',
method: 'post',
data
})
}
//获取站点拥有的闲鱼商品业务模式
export function site_business_model(data) {
return request({
url: 'xy_shop/site_business_model',
method: 'post',
data
})
}

40
src/api/xyshop.js Normal file
View File

@ -0,0 +1,40 @@
import request from '@axioshooks';
//创建闲鱼店铺
export function save_shop(data) {
return request({
url: 'xy_openapi/auth/save_shop',
method: 'post',
data
})
}
//编辑闲鱼店铺
export function update_shop(data) {
return request({
url: 'xy_openapi/auth/update_shop',
method: 'post',
data
})
}
//删除闲鱼店铺
export function delById(data) {
return request({
url: `xy_openapi/auth/delById/${data}`,
method: 'delete',
})
}
//查询店铺列表
export function list_shop(data) {
return request({
url: 'xy_openapi/auth/list_shop',
method: 'get',
data
})
}
//上传图片
export function upload(data) {
return request({
url: 'xy_openapi/upload',
method: 'file',
data
})
}

View File

@ -97,7 +97,7 @@ const onNavTo=(path)=>{
.breadcrumbbox{ .breadcrumbbox{
color: #000; color: #000;
flex:1; flex:1;
height:100%; height:40px;
width:100%; width:100%;
&::-webkit-scrollbar{ &::-webkit-scrollbar{
display: none; display: none;

View File

@ -1,23 +1,44 @@
<template> <template>
<header class="headerbox" v-if="showslider"> <header class="headerbox" v-if="showslider">
<Breadcrumb/> <Breadcrumb />
<div class="flex items-center"> <div class="flex items-center">
<el-popover <el-popover
placement="bottom" placement="bottom"
width="290" width="290"
trigger="hover" trigger="hover"
v-model="store.infovisible"> v-model="store.infovisible"
>
<template #reference> <template #reference>
<div <div
style="font-size:15px;font-weight:bold; cursor: pointer;max-width:156px;white-space: nowrap;text-overflow:ellipsis;overflow:hidden;padding:0 16px;color:#101010;"> style="
<span> {{ userinfo.truename.slice(0,7) }}</span> font-size: 15px;
<el-icon @click="store.infovisible=!store.infovisible"><CaretTop v-if="store.infovisible"/><CaretBottom v-if="!store.infovisible"/></el-icon> font-weight: bold;
cursor: pointer;
max-width: 156px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
padding: 0 16px;
color: #101010;
"
>
<span> {{ userinfo ? userinfo.nick_name : "退出登录" }}</span>
<el-icon @click="store.infovisible = !store.infovisible"
><CaretTop v-if="store.infovisible" /><CaretBottom
v-if="!store.infovisible"
/></el-icon>
</div> </div>
</template> </template>
<ul class="infopopverbox"> <ul class="infopopverbox" v-if="userinfo">
<li @click.stop="onCopy(userinfo.username)" class="font14 bold">{{userinfo.username}}<img src="@assets/copy.png"/></li> <li @click.stop="onCopy(userinfo.username)" class="font14 bold">
<li @click.stop="onCopy(userinfo.company_unique_id)" class="font12 "><span class="gay">公司 ID</span><span style="margin-left:10px">{{userinfo.company_unique_id}}</span> {{ userinfo.username }}<img src="@assets/copy.png" />
<img src="@assets/copy.png"/> </li>
<li @click.stop="onCopy(userinfo.businesses_code)" class="font12">
<span class="gay">公司 ID</span
><span style="margin-left: 10px">{{
userinfo.businesses_code
}}</span>
<img src="@assets/copy.png" />
</li> </li>
</ul> </ul>
<!-- <div class="infopopvercenter"> <!-- <div class="infopopvercenter">
@ -27,181 +48,184 @@
<div class="outloginbtnbox"> <div class="outloginbtnbox">
<el-button class="outloginbtn" @click="logout">退出登录</el-button> <el-button class="outloginbtn" @click="logout">退出登录</el-button>
</div> </div>
</el-popover> </el-popover>
</div> </div>
</header> </header>
</template> </template>
<script setup> <script setup>
import Breadcrumb from './Breadcrumb.vue'; import Breadcrumb from "./Breadcrumb.vue";
import { useRouter } from 'vue-router'; import { useRouter } from "vue-router";
import { ref, watch,reactive,onMounted} from 'vue'; import { ref, watch, reactive, onMounted } from "vue";
import axioshooks from "@axioshooks"; import { copytext, delAllStorage } from "@services/commont";
import {copytext,delAllStorage} from "@services/commont"; import { getInfo } from "@/api/user.js";
import {
CaretTop,
CaretBottom,
} from '@element-plus/icons-vue';
const router = useRouter(); const router = useRouter();
const store=reactive({ const store = reactive({
infovisible:false infovisible: false,
}); });
const infovisible=ref(true); const infovisible = ref(true);
const showslider=ref(true); const showslider = ref(true);
watch(router.currentRoute,async(newpath,oldpath)=>{ watch(router.currentRoute, async (newpath, oldpath) => {
if(newpath.path=='/qualityreport'){ if (newpath.path == "/qualityreport") {
showslider.value=false; showslider.value = false;
}else{ } else {
showslider.value=true; showslider.value = true;
} }
}); });
onMounted(()=>{ onMounted(() => {
if(router.currentRoute.path=='/qualityreport'){ if (router.currentRoute.path == "/qualityreport") {
showslider.value=false; showslider.value = false;
}else{ } else {
showslider.value=true; showslider.value = true;
} }
}); });
const userinfo=ref({username:"",company_unique_id:"",truename:""}); const userinfo = ref({
axioshooks({ username: "",
url:"menu/get_userinfo", company_unique_id: "",
customHandler:(err,e)=>{ businesses_code: "",
if(!err&&e){ });
if(e.errcode==0){ getInfo().then((res) => {
userinfo.value=e.datas console.log(res, "res++++++++++++++++++++");
if (res.code === "200") {
userinfo.value = res.data;
} }
} });
} // axioshooks({
}); // url: "menu/get_userinfo",
// customHandler: (err, e) => {
// if (!err && e) {
// if (e.errcode == 0) {
// userinfo.value = e.datas;
// }
// }
// },
// });
const onCopy=(str)=>{ const onCopy = (str) => {
copytext(str); copytext(str);
} };
const logout=()=>{ const logout = () => {
location.href="/"; location.href = "/";
delAllStorage(); delAllStorage();
setTimeout(()=>{ setTimeout(() => {
location.reload(); location.reload();
},500); }, 500);
} };
</script>
</script>
<style lang="scss" scoped> <style lang="scss" scoped>
.headerbox{ .headerbox {
background:#f1f2f5; background: #f1f2f5;
padding:0px 12px; padding: 0px 12px;
box-sizing: border-box; box-sizing: border-box;
display:flex; display: flex;
align-items:center; align-items: center;
justify-content: space-between; justify-content: space-between;
height:38px; height: 38px;
} }
.infopopverbox{ .infopopverbox {
padding:16px; padding: 16px;
background:#FAFAFA; background: #fafafa;
box-sizing:border-box; box-sizing: border-box;
li{ li {
display:flex; display: flex;
align-items:center; align-items: center;
line-height:20px; line-height: 20px;
box-sizing:border-box; box-sizing: border-box;
padding:3px 0; padding: 3px 0;
color:var(--black); color: var(--black);
cursor: pointer; cursor: pointer;
img{ img {
margin-left:6px; margin-left: 6px;
width:12px; width: 12px;
height:12px; height: 12px;
} }
} }
.infopopversubbox{ .infopopversubbox {
padding:5px 0 0px; padding: 5px 0 0px;
display:flex; display: flex;
align-items:center; align-items: center;
box-sizing:border-box; box-sizing: border-box;
} }
.btnStyle{ .btnStyle {
border:1px solid #4091FF; border: 1px solid #4091ff;
color:#4091FF; color: #4091ff;
background:#fff; background: #fff;
border-radius:20px; border-radius: 20px;
height:20px; height: 20px;
font-weight:400; font-weight: 400;
padding:0px 12px; padding: 0px 12px;
box-sizing:border-box; box-sizing: border-box;
font-size:12px; font-size: 12px;
cursor: pointer; cursor: pointer;
} }
} }
.infopopvercenter{ .infopopvercenter {
display:flex; display: flex;
align-items:stretch; align-items: stretch;
padding:8px 16px; padding: 8px 16px;
box-sizing:border-box; box-sizing: border-box;
border-bottom:1px solid var(--lightGay); border-bottom: 1px solid var(--lightGay);
li{ li {
flex:1; flex: 1;
text-align:center; text-align: center;
position: relative; position: relative;
color:var(--gay); color: var(--gay);
font-size:12px; font-size: 12px;
cursor: pointer; cursor: pointer;
&:after{ &:after {
content:""; content: "";
position: absolute; position: absolute;
right:0; right: 0;
background:var(--lightGay); background: var(--lightGay);
height:17px; height: 17px;
width:1px; width: 1px;
} }
&:last-child{ &:last-child {
&:after{ &:after {
content:""; content: "";
display:none; display: none;
} }
} }
} }
} }
.infopopverbottom{ .infopopverbottom {
padding:6px 12px; padding: 6px 12px;
box-sizing:border-box; box-sizing: border-box;
li{ li {
padding:6px 0; padding: 6px 0;
box-sizing:border-box; box-sizing: border-box;
display:flex; display: flex;
color:var(--gay); color: var(--gay);
font-size:12px; font-size: 12px;
cursor: pointer; cursor: pointer;
img{ img {
width:16px; width: 16px;
height:16px; height: 16px;
margin-right:6px; margin-right: 6px;
} }
} }
} }
.outloginbtnbox{ .outloginbtnbox {
margin-top:60px; margin-top: 60px;
margin-bottom:16px; margin-bottom: 16px;
padding:0 12px; padding: 0 12px;
box-sizing:border-box; box-sizing: border-box;
.outloginbtn{ .outloginbtn {
width:100%; width: 100%;
font-size:12px; font-size: 12px;
font-weight:400; font-weight: 400;
color:#6F6D6D; color: #6f6d6d;
height:30px; height: 30px;
line-height:0px; line-height: 0px;
} }
} }
</style> </style>

View File

@ -0,0 +1,247 @@
<template>
<div class="text-msg-pic-upload">
<div class="uploadcontainer">
<div v-for="(item, index) in tempFileList" :key="index" class="prewimg">
<img :src="item.base64" />
<div></div>
</div>
<label for="uploadinput" class="inputlabel"> 上传 </label>
<input
type="file"
id="uploadinput"
class="fileinput"
multiple
accept="image/jpeg,image/png,image/gif,image/jpg"
:onChange="onUpload"
/>
</div>
<!-- <el-upload
ref="upload"
id="upload"
list-type="picture-card"
:class="{ display: data.uploadDisabled }"
v-model:file-list="tempFileList"
:multiple="props.multiple"
:auto-upload="props.autoUpload"
:on-exceed="handleExceed"
:on-change="onChange"
accept="jpeg"
:show-file-list="props.limit > 1 || !props.limit"
>
<el-icon v-if="props.limit > 1 || tempFileList.length == 0"
><Plus
/></el-icon>
<img
:src="tempFileList[0].url"
v-if="props.limit == 1 && tempFileList.length > 0"
class="showimg"
/>
<template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="hImgPreview(file)"
>
<el-icon><zoom-in /></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<el-icon><Delete /></el-icon>
</span>
</span>
</div>
</template>
</el-upload> -->
<el-dialog v-model="data.dialogVisible" append-to-body>
<img width="100%" :src="data.dialogImageUrl" alt="" />
</el-dialog>
<!-- <div class="Upload_pictures">
<ul class="el-upload__tip cBBBDBF" style="color: #bbbdbf">
<li>支持PNGJEPG格式 不超过2MB</li>
</ul>
</div> -->
</div>
</template>
<script setup>
import { ref, reactive, watch, computed, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
const $emit = defineEmits(["onSuccessFiles"]);
const props = defineProps({
limitType: {
type: Array,
default: ["jpeg", "jpg", "gif", "png"],
}, //
autoUpload: Boolean,
limit: Number, //
imgList: Array, //
multiple: Boolean, //
});
const data = reactive({
// el-upload使
uploadDisabled: false,
dialogImageUrl: "",
dialogVisible: false,
});
const tempFileList = ref([]);
const onUpload = (e) => {
const ImgList = [];
for (let i = 0; i < e.target.files.length; i++) {
if (isPngImage(e.target.files[i])) {
let file = isPngImage(e.target.files[i]);
const render = new FileReader();
render.onload = (re) => {
ImgList.push({ file: file, base64: re.target.result });
if (e.target.files.length - 1 == i) {
if (!handleExceed(ImgList, tempFileList.value)) return;
tempFileList.value.push(...ImgList);
$emit("onSuccessFiles", tempFileList.value);
}
};
render.readAsDataURL(file);
}
}
};
const isPngImage = (file) => {
if (!file.type.startsWith("image/")) {
console.error("这不是一个图片文件");
return false;
}
const fileName = file.name || "";
const extension = fileName.split(".").pop().toLowerCase();
if (props.limitType.includes(extension)) return file;
};
watch(
props,
(newval) => {
// if (Array.isArray(props.imgList)) {
// console.log(
// props.imgList,
// "props.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgList"
// );
// tempFileList.value = props.imgList||[];
// }
},
{ deep: true, immediate: true }
);
//
const hImgPreview = (file) => {
data.dialogImageUrl = file.url;
data.dialogVisible = true;
};
//
const handleRemove = (file) => {
if (tempFileList.value) {
const list = tempFileList.value.filter((f) => f.url != file.url);
$emit("onSuccessFiles", list);
} else {
$emit("onSuccessFiles", []);
}
return true;
};
const onChange = (file) => {
// if (!file || !file.raw) {
// return;
// }
// let types = props.limitType;
// const isImage = types.find((f) => file.raw.type.includes(f));
// const isLt20M = file.raw.size / 1024 / 1024 < 2;
// if (!isImage && props.limit > 1) {
// ElMessage(
// types.length == 0
// ? " PNG !"
// : " JPGPNG !"
// );
// return false;
// }
// if (!isLt20M) {
// ElMessage(" 2MB!");
// return false;
// }
// isPngImage(file.raw);
// $emit("onSuccessFiles", tempFileList.value);
// return false;
};
//
const handleUpload = (op, filelist) => {};
const handleExceed = (files, fileList) => {
console.log(files.length + fileList.length, "files.length + fileList.length");
if (files.length + fileList.length > props.limit) {
ElMessage(
`当前限制选择 ${props.limit} 个文件,本次选择了 ${
files.length
} 个文件共选择了 ${files.length + fileList.length} 个文件`
);
return false;
}
return true;
};
</script>
<style lang="scss">
.text-msg-pic-upload .el-upload--picture-card,
.text-msg-pic-upload .el-upload-list--picture-card .el-upload-list__item {
width: 62px;
height: 62px;
line-height: 72px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 10px 0 0;
}
.showimg {
width: 60px;
height: 60px;
}
.display .el-upload--picture-card {
display: none;
}
.el-upload-list__item-delete {
margin-left: 10px !important;
}
.inputlabel {
display: flex;
align-items: center;
justify-content: center;
width: 80px;
height: 80px;
border: 1px dashed #e5e5e5;
border-radius: 6px;
&:hover {
border: 1px dashed #409eff;
}
}
.uploadcontainer {
display: flex;
align-items: stretch;
gap: 10px;
}
.fileinput {
display: none;
}
.prewimg {
width: 80px;
height: 80px;
border: 1px solid #e5e5e5;
border-radius: 6px;
display: block;
img {
width: 100%;
height: 100%;
display: block;
}
}
</style>

View File

@ -1,24 +1,23 @@
<template> <template>
<div class="text-msg-pic-upload"> <div class="text-msg-pic-upload">
<el-upload <el-upload
:class="{ display: data.uploadDisabled }"
action=""
list-type="picture-card"
ref="upload" ref="upload"
list-type="picture-card"
:class="{ display: data.uploadDisabled }"
v-model:file-list="tempFileList"
:multiple="props.multiple"
:auto-upload="props.autoUpload" :auto-upload="props.autoUpload"
v-model:file-list="data.tempFileList"
:on-exceed="handleExceed" :on-exceed="handleExceed"
:on-success="handleSuccess" :on-change="onChange"
accept="jpg,.jpeg,.png,.JPG,.JPEG"
:on-change="beforeUpload"
:show-file-list="props.limit > 1 || !props.limit" :show-file-list="props.limit > 1 || !props.limit"
accept="image/jpeg,image/png,image/gif,image/jpg"
> >
<el-icon v-if="props.limit > 1 || data.tempFileList.length == 0" <el-icon v-if="props.limit > 1 || tempFileList.length == 0"
><Plus ><Plus
/></el-icon> /></el-icon>
<img <img
:src="data.tempFileList[0].url" :src="tempFileList[0].url"
v-if="props.limit == 1 && data.tempFileList.length > 0" v-if="props.limit == 1 && tempFileList.length > 0"
class="showimg" class="showimg"
/> />
<template #file="{ file }"> <template #file="{ file }">
@ -27,12 +26,11 @@
<span class="el-upload-list__item-actions"> <span class="el-upload-list__item-actions">
<span <span
class="el-upload-list__item-preview" class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)" @click="hImgPreview(file)"
> >
<el-icon><zoom-in /></el-icon> <el-icon><zoom-in /></el-icon>
</span> </span>
<span <span
v-if="!data.uploadDisabled"
class="el-upload-list__item-delete" class="el-upload-list__item-delete"
@click="handleRemove(file)" @click="handleRemove(file)"
> >
@ -41,7 +39,6 @@
</span> </span>
</div> </div>
</template> </template>
<div class="el-upload__tip" v-if="props.tipsFlag">{{ props.tips }}</div>
</el-upload> </el-upload>
<el-dialog v-model="data.dialogVisible" append-to-body> <el-dialog v-model="data.dialogVisible" append-to-body>
<img width="100%" :src="data.dialogImageUrl" alt="" /> <img width="100%" :src="data.dialogImageUrl" alt="" />
@ -57,54 +54,61 @@
<script setup> <script setup>
import { ref, reactive, watch, computed } from "vue"; import { ref, reactive, watch, computed } from "vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { initOss } from "@services/commont";
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue"; import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
const $emit = defineEmits(["onSuccessFiles"]); const $emit = defineEmits(["onSuccessFiles"]);
const props = defineProps({ const props = defineProps({
width: String, limitType: {
type: Array,
default: ["jpeg", "jpg", "gif", "png"],
}, //
autoUpload: Boolean, autoUpload: Boolean,
limit: Number, limit: Number, //
limitType: Array, imgList: Array, //
disabled: Boolean, multiple: Boolean, //
imgList: Array,
tipsFlag: Boolean,
tips: String,
}); });
const data = reactive({ const data = reactive({
// el-upload使 // el-upload使
tempFileList: [],
host: "", //
uploadDisabled: false, uploadDisabled: false,
dialogImageUrl: "", dialogImageUrl: "",
dialogVisible: false, dialogVisible: false,
}); });
const tempFileList = ref([]);
watch( watch(
props, props,
(newval) => { (newval) => {
console.log(newval, "newval");
if (Array.isArray(props.imgList)) { if (Array.isArray(props.imgList)) {
console.log(props.imgList, "props.imgList"); tempFileList.value = props.imgList;
data.tempFileList = props.imgList;
} }
}, },
{ deep: true } { deep: true, immediate: true }
); );
computed(() => {
const upText = computed(() => {
return props.autoUpload ? "上传文件" : "选择文件"; return props.autoUpload ? "上传文件" : "选择文件";
}); });
const handlePictureCardPreview = (file) => { //
const hImgPreview = (file) => {
data.dialogImageUrl = file.url; data.dialogImageUrl = file.url;
data.dialogVisible = true; data.dialogVisible = true;
}; };
const beforeUpload = (file) => { //
const handleRemove = (file) => {
if (tempFileList.value) {
const list = tempFileList.value.filter((f) => f.url != file.url);
$emit("onSuccessFiles", list);
} else {
$emit("onSuccessFiles", []);
}
return true;
};
const onChange = (file) => {
if (!file || !file.raw) { if (!file || !file.raw) {
return; return;
} }
// console.log('beforeUpload', file) let types = props.limitType;
let types = props.limitType || ["jpeg", "jpg", "gif", "png"];
const isImage = types.find((f) => file.raw.type.includes(f)); const isImage = types.find((f) => file.raw.type.includes(f));
const isLt20M = file.raw.size / 1024 / 1024 < 2; const isLt20M = file.raw.size / 1024 / 1024 < 2;
@ -120,58 +124,23 @@ const beforeUpload = (file) => {
ElMessage("上传图片大小不能超过 2MB!"); ElMessage("上传图片大小不能超过 2MB!");
return false; return false;
} }
if (props.limit == 1) {
tempFileList.value = [];
}
handleUpload({ file: file }); handleUpload({ file: file });
return false; return false;
}; };
// //
const handleUpload = (op) => { const handleUpload = (op, filelist) => {
console.log(op.file, "handleUpload");
initOss(op.file.raw)
.then((link) => {
console.log(link, "link");
let tempFileList = [];
if (props.limit == 1) { if (props.limit == 1) {
tempFileList = [op.file]; tempFileList.value = [];
} else { setTimeout(() => {
tempFileList.push(...data.tempFileList, op.file); tempFileList.value = [op.file];
}, 100);
} }
$emit("onSuccessFiles", link, tempFileList); $emit("onSuccessFiles", op.file);
})
.catch((err) => {
console.log(err, "err");
$emit("onSuccessFiles", "", []);
});
}; };
//
const handleSuccess = (response, file, fileList) => {
// this.filterFileFn(fileList)
};
//
const filterFileFn = (fileList) => {
// let filterArr = fileList
// .filter(item => !item.status || item.status !== 'ready') //
// .map(item => {
// let url = item.response ? item.response.url : item.url
// return {
// url: url, // item.url || item.response.url
// name: item.name
// }
// })
// // console.log('fileList', fileList)
// this.$emit('onSuccessFiles', filterArr)
};
//
const handleRemove = (file, fileList) => {
if (data.tempFileList) {
const list = data.tempFileList.filter((f) => f.url != file.url);
$emit("onSuccessFiles", "", list);
} else {
$emit("onSuccessFiles", "", []);
$emit("onSuccessFiles", "", []);
}
return true;
};
const handleExceed = (files, fileList) => { const handleExceed = (files, fileList) => {
ElMessage( ElMessage(
`当前限制选择 ${props.limit} 个文件,本次选择了 ${ `当前限制选择 ${props.limit} 个文件,本次选择了 ${
@ -179,9 +148,6 @@ const handleExceed = (files, fileList) => {
} 个文件共选择了 ${files.length + fileList.length} 个文件` } 个文件共选择了 ${files.length + fileList.length} 个文件`
); );
}; };
const beforeRemove = () => {
// return this.$confirm(` ${file.name}`)
};
</script> </script>
<style lang="scss"> <style lang="scss">
@ -193,6 +159,7 @@ const beforeRemove = () => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 0 10px 0 0;
} }
.showimg { .showimg {
width: 60px; width: 60px;
@ -201,5 +168,8 @@ const beforeRemove = () => {
.display .el-upload--picture-card { .display .el-upload--picture-card {
display: none; display: none;
} }
.el-upload-list__item-delete {
margin-left: 10px !important;
}
</style> </style>

View File

@ -1,6 +1,6 @@
import axios, * as defaultAxios from 'axios'; import axios, * as defaultAxios from 'axios';
import { getStorage, deloneStorage } from "./commont"; import { getStorage, deloneStorage, jsonurldata } from "./commont";
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
@ -37,6 +37,7 @@ let _window = window;
let cancelTokenSource = null; let cancelTokenSource = null;
let lasturl = []; let lasturl = [];
export default ({ export default ({
url, url,
method = 'post', method = 'post',
@ -66,27 +67,44 @@ export default ({
}; };
let axioshooks = axios.create(); let axioshooks = axios.create();
let config = {
headers: Object.assign({}, headers) var axiosfn = {
}; "delete": (url, paramdata, config) => {
let newurl = url
let str = data && Object.keys(data).length > 0 ? "/" + jsonurldata(data) : ""
newurl = url + str
return axios.delete(newurl, config)
}, "post": axios.post, "get": (url, paramdata, config) => {
let newurl = url
let str = data && Object.keys(data).length > 0 ? "/" + jsonurldata(data) : ""
newurl = url + str
return axios.get(newurl, config)
}, "put": axios.put
}
const token = getStorage('token'); const token = getStorage('token');
const virtoken = getStorage('virtoken'); const virtoken = getStorage('virtoken');
const baseApi = import.meta.env.VITE_APP_BASE_API;
let newurl = ''; let newurl = '';
if (/http/.test(url)) { if (/http/.test(url)) {
newurl = url; newurl = url;
} else { } else {
const baseApi = import.meta.env.VITE_APP_BASE_API;
newurl = baseApi + '/api/' + url; newurl = baseApi + '/api/' + url;
} }
let newtoken = newurl.indexOf(baseApi) > -1 ? "Bearer " + virtoken : token;
let config = {
headers: Object.assign({}, headers, {
token: newtoken
})
};
cancelTokenSource = CancelToken.source(); cancelTokenSource = CancelToken.source();
if (token) { if (token) {
config = { config = {
headers: Object.assign({}, { headers: Object.assign({}, {
token: token, token: newtoken,
'Content-Type': 'application/json;' 'Content-Type': 'application/json;'
}, headers), }, headers),
cancelToken: cancelTokenSource.token, cancelToken: cancelTokenSource.token,
@ -101,22 +119,17 @@ export default ({
}//添加请求头 }//添加请求头
} }
if (method && method == 'get') { if (method && method == 'get') {
config.headers = Object.assign({}, { config.headers = Object.assign({}, config.headers || {}, headers);
token: token,
cancelToken: cancelTokenSource.token,
}, headers);
axioshooks = axios.get;
} else if (method && method == 'file') { } else if (method && method == 'file') {
config.headers = Object.assign({}, {
token: token, config.headers = Object.assign({}, config.headers || {}, {
token: newtoken,
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
Accept: '*/*', Accept: '*/*',
}, headers); }, headers);
axioshooks = axios.post;
} else {
axioshooks = axios.post;
} }
console.log(config,"config") axioshooks = axiosfn[method] ? axiosfn[method] : axios.post
// console.log(config,"config")
if (!url || !dispatchEffect()) return; if (!url || !dispatchEffect()) return;
// ONLY trigger by query // ONLY trigger by query
@ -131,9 +144,12 @@ console.log(config,"config")
_Object.values(data).map((d, index) => { _Object.values(data).map((d, index) => {
if ((d && d != '') || typeof d == 'number') { if ((d && d != '') || typeof d == 'number') {
if (Object.keys(data)[index] == 'file') { if (Object.keys(data)[index] == 'file') {
params.append('file', d, d.name); d.map((h)=>{
params.append('file', h, h.name);
})
} else if (Object.keys(data)[index] == 'filekey') { } else if (Object.keys(data)[index] == 'filekey') {
params.append(d, data[d], data[d].name); params.append(d, data[d]);
} else { } else {
params.append(Object.keys(data)[index], d); params.append(Object.keys(data)[index], d);
} }
@ -165,10 +181,8 @@ console.log(config,"config")
paramsdata = params; paramsdata = params;
} }
} }
axioshooks(newurl, paramsdata, config) axioshooks(newurl, paramsdata, config)
.then(response => { .then(response => {
console.log(response,"response")
if (response.data && response.data.errcode && response.data.errcode == 1002) { if (response.data && response.data.errcode && response.data.errcode == 1002) {
deloneStorage("token"); deloneStorage("token");
location.href = "/"; location.href = "/";
@ -187,7 +201,7 @@ console.log(config,"config")
} }
}) })
.catch(error => { .catch(error => {
console.log(error,"error") // console.log(error,"error")
if (!isCancel(error.message)) { if (!isCancel(error.message)) {
handler(error.message, error, null); handler(error.message, error, null);
reject(error.message); reject(error.message);

View File

@ -2,20 +2,18 @@ import { ElMessage } from 'element-plus';
import axioshooks from './axioshooks.js'; import axioshooks from './axioshooks.js';
export async function getFileMenu() { export async function getFileMenu() {
var filemoduleMap=import.meta.glob(["./../views/**/*.vue","./../views/*.vue"]); var filemoduleMap = import.meta.glob(["./../views/**/*.vue", "./../views/*.vue"]);
let results=[]; let results = [];
Object.keys(filemoduleMap).map((k,i)=>{ Object.keys(filemoduleMap).map((k, i) => {
let defaultmenu=filemoduleMap[k]; let defaultmenu = filemoduleMap[k];
const matches=k.match(/[^\.\/]+/g).slice(1,-1); const matches = k.match(/[^\.\/]+/g).slice(1, -1);
let path=""; let path = "";
console.log(matches,'matches'); matches.map((h) => {
matches.map((h)=>{ path += h + '/';
path+=h+'/';
}); });
path=path.slice(0,path.length-1); path = path.slice(0, path.length - 1);
console.log(path,'path') let data = { path: '/' + path, module: defaultmenu, url: k }
let data={path:'/'+path,module:defaultmenu,url:k}
results.push(data); results.push(data);
}); });
return results; return results;
@ -42,7 +40,8 @@ export function maskData(input, type = 'phone') {
const [localPart, domain] = input.split('@') const [localPart, domain] = input.split('@')
if (localPart.length > 2) { if (localPart.length > 2) {
start = 2 start = 2
end = domain.length + 1 } end = domain.length + 1
}
break break
} }
case 'bankCard': { case 'bankCard': {
@ -75,19 +74,18 @@ export function maskData(input, type = 'phone') {
default: // phone 包含手机号和固定电话 default: // phone 包含手机号和固定电话
// 手机号,保留前三位和后两位,电话号码保留区号和后三位 // 手机号,保留前三位和后两位,电话号码保留区号和后三位
// telRegExp-固定电话正则 phoneRegExp-手机号正则 // telRegExp-固定电话正则 phoneRegExp-手机号正则
let telRegExp=/^(?:(?:\+|00)86)?1\d{10}$/; let telRegExp = /^(?:(?:\+|00)86)?1\d{10}$/;
if (telRegExp.test(input)) { if (telRegExp.test(input)) {
let matchRes = input.match(telRegExp); let matchRes = input.match(telRegExp);
if(matchRes){ if (matchRes) {
console.log(matchRes,"matchRes") if (matchRes[1] && matchRes[1].length) {
if(matchRes[1]&&matchRes[1].length){
start = matchRes[1].length start = matchRes[1].length
}else{ } else {
start = 3 start = 3
} }
if(matchRes[2]&&matchRes[2].length){ if (matchRes[2] && matchRes[2].length) {
end = matchRes[2].length end = matchRes[2].length
}else{ } else {
end = 2 end = 2
} }
} }
@ -101,39 +99,39 @@ export function maskData(input, type = 'phone') {
// 使用正则表达式进行脱敏处理 // 使用正则表达式进行脱敏处理
const reg = new RegExp(`^(.{${start}}).*(.{${end}})$`) const reg = new RegExp(`^(.{${start}}).*(.{${end}})$`)
return input.replace(reg, `$1${'*'.repeat(maskLength)}$2`) return input.replace(reg, `$1${'*'.repeat(maskLength)}$2`)
} }
//获取近几天 //获取近几天
export function getDay (number,bool = false) { export function getDay(number, bool = false) {
let today = new Date(); let today = new Date();
let day = today.getTime() + 24 * 60 * 60 * 1000 * number; let day = today.getTime() + 24 * 60 * 60 * 1000 * number;
today.setTime(day); today.setTime(day);
let val = formatDate(parseInt(today.getTime() / 1000), 'Y-m-d') let val = formatDate(parseInt(today.getTime() / 1000), 'Y-m-d')
if(bool){ if (bool) {
val = parseInt(today.getTime() / 1000) val = parseInt(today.getTime() / 1000)
} }
return val return val
} }
export function getMonthFirst (data) { export function getMonthFirst(data) {
let date = new Date(data); let date = new Date(data);
date.setDate(1); date.setDate(1);
let month = parseInt(date.getMonth() + 1); let month = parseInt(date.getMonth() + 1);
let day = date.getDate(); let day = date.getDate();
if( month < 10) { if (month < 10) {
month = '0' + month month = '0' + month
} }
if(day < 10 ) { if (day < 10) {
day = '0' + day day = '0' + day
} }
let val = date.getFullYear() + '-' + month +'-' + day let val = date.getFullYear() + '-' + month + '-' + day
return val return val
} }
export function getMonthLast (data) { export function getMonthLast(data) {
let date = new Date(data); let date = new Date(data);
let currentMonth = date.getMonth(); let currentMonth = date.getMonth();
let nextMonth = ++currentMonth; let nextMonth = ++currentMonth;
@ -142,20 +140,20 @@ export function getMonthLast (data) {
let lastTime = new Date(nextMonthFirstDay - oneDay); let lastTime = new Date(nextMonthFirstDay - oneDay);
let month = parseInt(lastTime.getMonth() + 1); let month = parseInt(lastTime.getMonth() + 1);
let day = lastTime.getDate(); let day = lastTime.getDate();
if( month < 10) { if (month < 10) {
month = '0' + month month = '0' + month
} }
if(day < 10 ) { if (day < 10) {
day = '0' + day day = '0' + day
} }
let val = date.getFullYear() + '-' + month +'-' + day let val = date.getFullYear() + '-' + month + '-' + day
return val return val
} }
//格式化时间 //格式化时间
export function uuid(){ export function uuid() {
var s = []; var s = [];
var hexDigits = "0123456789abcdef"; var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) { for (var i = 0; i < 36; i++) {
@ -178,36 +176,35 @@ export function getQueryString(e) {
} }
// 添加本地存储 // 添加本地存储
export function addSessionStorage(key,value) { export function addSessionStorage(key, value) {
console.log(key,value,"9888978787"); try {
try{ sessionStorage.setItem(key, JSON.stringify(value));
sessionStorage.setItem(key,JSON.stringify(value)); } catch (err) {
}catch(err){
} }
} }
export function getSessionStorage(key) { export function getSessionStorage(key) {
let result=sessionStorage.getItem(key); let result = sessionStorage.getItem(key);
try{ try {
result= JSON.parse(result); result = JSON.parse(result);
}catch(err){ } catch (err) {
} }
return result; return result;
} }
export function delSessionStorage(key) { export function delSessionStorage(key) {
sessionStorage.removeItem(key); sessionStorage.removeItem(key);
} }
// 添加本地存储 // 添加本地存储
export function addStorage(key,value) { export function addStorage(key, value) {
localStorage.setItem(key,JSON.stringify(value)); localStorage.setItem(key, JSON.stringify(value));
} }
// 获取本地存储 // 获取本地存储
export function getStorage(key) { export function getStorage(key) {
let result=localStorage.getItem(key); let result = localStorage.getItem(key);
try{ try {
result= JSON.parse(result); result = JSON.parse(result);
}catch(err){ } catch (err) {
} }
return result; return result;
} }
@ -222,6 +219,7 @@ export function delAllStorage(key) {
} }
// JSON数据转换 url后的参数格式 // JSON数据转换 url后的参数格式
export function jsonurldata(datas) { export function jsonurldata(datas) {
if (typeof datas !== "object") return datas
const dataarray = []; const dataarray = [];
const datakeys = Array.from(Object.keys(datas)); const datakeys = Array.from(Object.keys(datas));
const datavalue = Array.from(Object.values(datas)); const datavalue = Array.from(Object.values(datas));
@ -232,17 +230,17 @@ export function jsonurldata(datas) {
let outdata = dataarray.join('&'); let outdata = dataarray.join('&');
return outdata; return outdata;
} }
export function isWeiXin(){ export function isWeiXin() {
let ua = window.navigator.userAgent.toLowerCase(); let ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){ if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true; return true;
}else{ } else {
return false; return false;
} }
} }
//把时间戳格式化成标准格式 第一个参数为时间戳,第二个参数为格式例如 Y-m-d h:M:s' //把时间戳格式化成标准格式 第一个参数为时间戳,第二个参数为格式例如 Y-m-d h:M:s'
export function formatDate(date, format) { export function formatDate(date, format) {
if(!date){ if (!date) {
return '' return ''
} }
const days = [ const days = [
@ -254,7 +252,7 @@ export function formatDate(date, format) {
'周五', '周五',
'周六' '周六'
]; ];
if ( typeof date == 'string') { if (typeof date == 'string') {
if (date.length < 13) { if (date.length < 13) {
const j = 13 - date.length; const j = 13 - date.length;
for (let i = 0; i < j; i++) { for (let i = 0; i < j; i++) {
@ -262,9 +260,9 @@ export function formatDate(date, format) {
} }
} }
date = new Date(Number(date)); date = new Date(Number(date));
}else if (typeof date == 'number'){ } else if (typeof date == 'number') {
if(date<1000000000000){ if (date < 1000000000000) {
date=date*1000; date = date * 1000;
} }
date = new Date(date); date = new Date(date);
} else if (typeof date === 'undefined') { } else if (typeof date === 'undefined') {
@ -313,7 +311,7 @@ export function formatDate(date, format) {
return format; return format;
}; };
// 压缩图片 // 压缩图片
export function compression(imgsrc, truewidth,trueheight) { export function compression(imgsrc, truewidth, trueheight) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const cts = canvas.getContext('2d'); const cts = canvas.getContext('2d');
@ -322,17 +320,17 @@ export function compression(imgsrc, truewidth,trueheight) {
newimg.onload = function () { newimg.onload = function () {
let _w = newimg.naturalWidth; let _w = newimg.naturalWidth;
let _h = newimg.naturalHeight; let _h = newimg.naturalHeight;
const trueheightarray=[]; const trueheightarray = [];
if(trueheight){ if (trueheight) {
trueheightarray.push(trueheight); trueheightarray.push(trueheight);
}else{ } else {
let trueheight = _h / _w * truewidth; let trueheight = _h / _w * truewidth;
trueheightarray.push(trueheight); trueheightarray.push(trueheight);
} }
canvas.width = truewidth; canvas.width = truewidth;
canvas.height = trueheightarray[0]; canvas.height = trueheightarray[0];
cts.drawImage(newimg, 0, 0, _w, _h, 0, 0, truewidth, trueheightarray[0]); cts.drawImage(newimg, 0, 0, _w, _h, 0, 0, truewidth, trueheightarray[0]);
resolve(canvas.toDataURL('images/png',0.8)); resolve(canvas.toDataURL('images/png', 0.8));
} }
}) })
} }
@ -347,22 +345,22 @@ export function isArray(value) {
return Array.isArray(value); return Array.isArray(value);
} }
export function debunce(fn,delay=1000) { export function debunce(fn, delay = 1000) {
let timer; let timer;
return function(...args){ return function (...args) {
if(timer){ if (timer) {
clearTimeout(timer); clearTimeout(timer);
} }
timer=setTimeout(()=>{ timer = setTimeout(() => {
fn.apply(this,args); fn.apply(this, args);
},delay); }, delay);
} }
} }
export function copytext(text){ export function copytext(text) {
try { try {
const textToCopy = text; const textToCopy = text;
navigator.clipboard.writeText(textToCopy); navigator.clipboard.writeText(textToCopy);
@ -372,76 +370,74 @@ export function copytext(text){
ElMessage({ type: 'waning', message: '该浏览器不支持自动复制' }) ElMessage({ type: 'waning', message: '该浏览器不支持自动复制' })
} }
} }
export const initOss=(file)=>{ export const initOss = (file) => {
return new Promise((r,j)=>{ return new Promise((r, j) => {
let oss=getSessionStorage("oss"); let oss = getSessionStorage("oss");
console.log(oss,"oss"); if (oss) {
if(oss){ const key = oss.dir + new Date().getTime() + (99999) * Math.random() + '.png';
const key = oss.dir +new Date().getTime()+(99999)*Math.random()+'.png'; if (oss.expire > Number(new Date().getTime().toString().slice(0, 10))) {
if(oss.expire>Number(new Date().getTime().toString().slice(0,10))){ sendoss({ key, file, ...oss });
sendoss({ key, file, ... oss }); } else {
}else{
delSessionStorage("oss"); delSessionStorage("oss");
getSign(); getSign();
} }
}else{ } else {
getSign(); getSign();
} }
function getSign(){ function getSign() {
const baseApi = import.meta.env.VITE_APP_BASE_URL;
axioshooks({ axioshooks({
url:"base_config/get_oss_sign_aliyun_v3", url: baseApi+"/api/base_config/get_oss_sign_aliyun_v3",
data:{bussiness_type:"xy_shop_qc_avatar"}, data: { bussiness_type: "xy_shop_qc_avatar" },
customHandler:(err,res)=>{ customHandler: (err, res) => {
if(!err&&res){ if (!err && res) {
if(res.errcode==0){ if (res.errcode == 0) {
let oss=Object.assign({},res.datas); let oss = Object.assign({}, res.datas);
const key = oss.dir +new Date().getTime()+(99999)*Math.random()+'.png'; const key = oss.dir + new Date().getTime() + (99999) * Math.random() + '.png';
oss.accessKeyId = res.datas.accessid; oss.accessKeyId = res.datas.accessid;
oss.accessKeySecret = res.datas.signature; oss.accessKeySecret = res.datas.signature;
addSessionStorage('oss',oss); addSessionStorage('oss', oss);
sendoss({ key, file, ... oss }); sendoss({ key, file, ...oss });
}else{ } else {
j(); j();
ElMessage("上传失败:"+res.msg); ElMessage("上传失败:" + res.msg);
} }
} }
} }
}).catch((err)=>{ }).catch((err) => {
j(); j();
ElMessage("上传失败"); ElMessage("上传失败");
}); });
} }
function sendoss(data){ function sendoss(data) {
// OSS 的 POST 请求 URL // OSS 的 POST 请求 URL
const url = 'https://'+data.host; const url = 'https://' + data.host;
// 创建一个 FormData 实例 // 创建一个 FormData 实例
const formData = new FormData(); const formData = new FormData();
// 添加字段到 formData // 添加字段到 formData
formData.append('key',data.key); formData.append('key', data.key);
formData.append('policy', data.policy); formData.append('policy', data.policy);
formData.append('OSSAccessKeyId',data.accessid); formData.append('OSSAccessKeyId', data.accessid);
formData.append('Signature',data.signature); formData.append('Signature', data.signature);
formData.append('success_action_status', 201); formData.append('success_action_status', 201);
formData.append('file', data.file,data.file.name); formData.append('file', data.file, data.file.name);
let resulturl=url+'/'+data.key; let resulturl = url + '/' + data.key;
fetch(url, { fetch(url, {
method: 'POST', // 或者 'PUT' method: 'POST', // 或者 'PUT'
body: formData, body: formData,
}).then((res)=>{ }).then((res) => {
console.log(res,"rrr",resulturl) if (res.status == 201) {
if(res.status==201){
r(resulturl); r(resulturl);
}else{ } else {
ElMessage("上传失败"); ElMessage("上传失败");
j(); j();
} }
}).catch((err)=>{ }).catch((err) => {
console.log(err.message,"err1") if (err.message == "Failed to fetch") {
if(err.message=="Failed to fetch"){
ElMessage("上传失败"); ElMessage("上传失败");
delSessionStorage("oss"); delSessionStorage("oss");
j(); j();
@ -452,26 +448,26 @@ export const initOss=(file)=>{
} }
let commont={ let commont = {
maskData:maskData, maskData: maskData,
copytext:copytext, copytext: copytext,
copytext:copytext, copytext: copytext,
getDay:getDay, getDay: getDay,
uuid:uuid, uuid: uuid,
addStorage:addStorage, addStorage: addStorage,
getStorage:getStorage, getStorage: getStorage,
deloneStorage:deloneStorage, deloneStorage: deloneStorage,
delAllStorage:delAllStorage, delAllStorage: delAllStorage,
formatDate:formatDate, formatDate: formatDate,
jsonurldata:jsonurldata, jsonurldata: jsonurldata,
isWeiXin:isWeiXin, isWeiXin: isWeiXin,
getQueryString:getQueryString, getQueryString: getQueryString,
getMonthLast:getMonthLast, getMonthLast: getMonthLast,
getMonthFirst:getMonthFirst, getMonthFirst: getMonthFirst,
compression:compression, compression: compression,
isObject:isObject, isObject: isObject,
isArray:isArray, isArray: isArray,
initOss:initOss initOss: initOss
} }

View File

@ -126,7 +126,6 @@ import { ElMessage } from "element-plus";
import axioshooks from "@axioshooks"; import axioshooks from "@axioshooks";
import { getStorage, addStorage } from "@services/commont"; import { getStorage, addStorage } from "@services/commont";
import { Loading } from "@element-plus/icons-vue"; import { Loading } from "@element-plus/icons-vue";
import Header from "../components/Layout/Header.vue";
const props = defineProps(["callback"]); const props = defineProps(["callback"]);
const ruleForm = reactive({ const ruleForm = reactive({
@ -158,9 +157,11 @@ const rules = ref({
}); });
const getCatchImage = () => { const getCatchImage = () => {
const baseApi = import.meta.env.VITE_APP_BASE_URL;
checkloading.value = true; checkloading.value = true;
axioshooks({ axioshooks({
url: "login/get_brand_img_tncode", url: baseApi + "/api/login/get_brand_img_tncode",
data: { username: ruleForm.username, password: ruleForm.password }, data: { username: ruleForm.username, password: ruleForm.password },
customHandler: (err, e) => { customHandler: (err, e) => {
if (!err && e) { if (!err && e) {
@ -191,8 +192,9 @@ const onCheckImg = () => {
const find = checkimages?.value?.model?.find( const find = checkimages?.value?.model?.find(
(f) => f.cate_map_id == checkvalue.value (f) => f.cate_map_id == checkvalue.value
); );
const baseApi = import.meta.env.VITE_APP_BASE_URL;
axioshooks({ axioshooks({
url: "login/xy_hosted_login", url: baseApi + "/api/login/xy_hosted_login",
data: { data: {
username: ruleForm.username, username: ruleForm.username,
password: ruleForm.password, password: ruleForm.password,
@ -207,9 +209,8 @@ const onCheckImg = () => {
checkimages.value = false; checkimages.value = false;
let token = e.datas.token; let token = e.datas.token;
if (e.datas.token) { if (e.datas.token) {
const baseApi = import.meta.env.VITE_APP_BASE_URL;
axioshooks({ axioshooks({
url: baseApi + "/api/auth/login3rd", url: "auth/login3rd",
headers: { headers: {
loginType: "erpLogin", loginType: "erpLogin",
token: e.datas.token, token: e.datas.token,
@ -219,7 +220,11 @@ const onCheckImg = () => {
console.log(e, "eee"); console.log(e, "eee");
if (e.code == "200") { if (e.code == "200") {
addStorage("token", token); addStorage("token", token);
addStorage("virtoken", e.data); // addStorage("virtoken", e.data);
addStorage(
"virtoken",
"9wEUErM0vX7OGuPq7byzZA0KdSMhROI8cCWvQAK5bH8TyOwHhekuHF0vwF9cMg5h92fVFtoZssQv9Oo36CYbZmXjrWa56NWWLNppUGRiTFEHYNzPhn7NYBP7SqvPPI6z"
);
if (props.callback) { if (props.callback) {
props.callback(); props.callback();
} }

View File

@ -0,0 +1,221 @@
<template>
<el-dialog
:title="props.specificationTitle"
v-model="props.specificationDialogVisible"
width="40%"
top="23vh"
:close-on-click-modal="false"
:before-close="specificationClose"
>
<div>
<div style="display: flex; align-items: center; margin-bottom: 10px">
<span style="font-size: 18px; display: flex; align-items: center"
><Warning style="width: 1em; height: 1em; margin-right: 8px" /></span
>最多添加两个商品规格单个规格最多添加50个属性值两个属性时相乘不得超过400个
</div>
<el-form
ref="ruleFormRef"
:model="ruleForm"
label-width="auto"
class="demo-ruleForm"
:rules="rules"
>
<el-form-item prop="name">
<el-input
v-model="ruleForm.name"
style="width: 280px"
placeholder="请输入商品规格字数限制4"
>
<template #suffix>
<el-button
type="primary"
size="small"
@click.stop="submit_specification(ruleFormRef)"
>确定</el-button
>
</template>
</el-input>
</el-form-item>
<div v-for="(item, index) in specification_list" :key="index">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<div>
<el-input
v-if="item.disabled"
class="title"
v-model="item.label"
size="small"
@keydown="item.keydown($event, item, index)"
>
<template #suffix>
<span>{{ `(${item.num})` }}</span>
</template>
</el-input>
<span v-else>{{ item.label }}{{ `(${item.num})` }}</span>
</div>
<div>
<el-button
style="margin-left: 0"
v-for="el in item.buttonGroup"
:key="el.label"
:type="el.type"
text
size="small"
@click="el.handler(item, index)"
>{{ el.label }}</el-button
>
</div>
</div>
<el-input
style="margin: 5px 0"
v-model="item.inputGroup.valueName"
:placeholder="item.inputGroup.placeholder"
@keydown="
item.inputGroup.keydown($event, item.inputGroup.valueName, index)
"
>
</el-input>
<div>
<el-button
style="margin: 2px 5px 2px 0px"
v-for="(el, ind) in item.valueGrop"
:key="ind"
:type="el.type"
round
size="small"
@click="el.delete(item, ind)"
>
{{ el.label }}<el-icon class="el-icon--right"><Delete /></el-icon>
</el-button>
</div>
</div>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="specificationClose">取消</el-button>
<el-button type="primary" @click="submitForm">{{ editText }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, defineEmits, defineProps, reactive } from "vue";
import { Warning, Delete } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
const $emit = defineEmits(["specificationClose"]);
const props = defineProps({
specificationDialogVisible: {
type: Boolean,
default: false,
},
specificationTitle: {
type: String,
default: "",
},
editText: {
type: String,
default: "确定",
},
specification_arr: {
type: Array,
default: [],
},
});
const ruleFormRef = ref(null);
const ruleForm = reactive({
name: "",
});
const rules = reactive({
name: [
{ min: 1, max: 4, message: "字数限制最多输入4个字符", trigger: "blur" },
],
});
const specification_list = ref(props.specification_arr);
const specification_list_index = ref(0);
const submit_specification = (formEl) => {
formEl.validate((valid) => {
if (!valid || !ruleForm.name) return;
if (specification_list.value.length >= 2)
return ElMessage.warning("超过输入限制!");
specification_list_index.value++;
specification_list.value.push({
label: ruleForm.name,
num: 0,
index: specification_list_index.value,
disabled: false,
keydown: (e, item, index) => {
if (e.key !== "Enter") return;
if (item.label.length <= 4) {
item.disabled = false;
} else {
ElMessage.warning("字数限制4个字符");
}
},
buttonGroup: [
{
type: "primary",
label: "编辑",
handler: (item) => {
item.disabled = true;
},
},
{
type: "danger",
label: "删除",
handler: (item, index) => {
specification_list.value.splice(index, 1);
},
},
],
inputGroup: {
valueName: "",
placeholder: "请输入规格属性,按回车健确认",
keydown: (e, name, index) => {
if (e.key !== "Enter" || !name) return;
if (specification_list.value.length <= 1) {
if (specification_list.value[index].valueGrop.length >= 10) return;
} else {
if (
specification_list.value[0].valueGrop.length *
specification_list.value[1].valueGrop.length >=
100
)
return;
}
specification_list.value[index].valueGrop.push({
type: "danger",
label: specification_list.value[index].inputGroup.valueName,
delete: (item, ind) => {
specification_list.value[index].valueGrop.splice(ind, 1);
},
});
specification_list.value[index].num =
specification_list.value[index].valueGrop.length;
specification_list.value[index].inputGroup.valueName = "";
},
},
valueGrop: [],
});
ruleForm.name = "";
});
};
const submitForm = () => {
$emit("specificationSubmit", specification_list);
specificationClose();
};
const specificationClose = () => {
$emit("specificationClose");
};
</script>
<style scoped lang='scss'>
</style>

File diff suppressed because it is too large Load Diff

View File

@ -59,8 +59,8 @@
<UploadImage <UploadImage
:limit="item.limit" :limit="item.limit"
:imgList="item.fileImgList" :imgList="item.fileImgList"
:autoUpload="false" :multiple="item.multiple"
@onSuccessFiles="item.handler" @onSuccessFiles="item.onSuccessFiles"
/> />
</div> </div>
</el-form-item> </el-form-item>
@ -81,7 +81,7 @@
import UploadImage from "@components/Upload/newfileupload.vue"; import UploadImage from "@components/Upload/newfileupload.vue";
import { ref, defineEmits, defineProps } from "vue"; import { ref, defineEmits, defineProps } from "vue";
const ruleFormRef = ref(null); const ruleFormRef = ref(null);
const $emit = defineEmits(["submitForm"]); const $emit = defineEmits(["submitForm", "CreateStoreClose"]);
const props = defineProps({ const props = defineProps({
CreateStoreDialogVisible: { CreateStoreDialogVisible: {
type: Boolean, type: Boolean,
@ -116,6 +116,7 @@ const submitForm = (form) => {
}; };
const CreateStoreClose = () => { const CreateStoreClose = () => {
$emit("CreateStoreClose"); $emit("CreateStoreClose");
ruleFormRef.value.resetFields();
}; };
</script> </script>

View File

@ -9,7 +9,7 @@
@click="operation('create')" @click="operation('create')"
>创建闲鱼店铺</el-button >创建闲鱼店铺</el-button
> >
<el-button class="btn" size="small" @click="operation()" <el-button class="btn" size="small" @click="operation('publish')"
>发布商品</el-button >发布商品</el-button
> >
</div> </div>
@ -21,20 +21,20 @@
:sm="10" :sm="10"
:md="8" :md="8"
:lg="6" :lg="6"
:xl="4" :xl="get_win_width"
v-for="(item, index) in 88" v-for="(item, index) in store_list"
:key="index" :key="index"
> >
<div class="card"> <div class="card">
<div class="card-top"> <div class="card-top">
<div class="top-left"> <div class="top-left">
<div class="block"> <div class="block">
<el-avatar shape="square" :size="50" :src="squareUrl" /> <el-avatar shape="square" :size="50" :src="item.lcon" />
</div> </div>
</div> </div>
<div class="top-right"> <div class="top-right">
<div class="info"> <div class="info">
<div class="username">账号名称</div> <!-- <div class="username">{{ item.xyName }}</div> -->
<div> <div>
<el-button <el-button
v-for="el in buttonGroup" v-for="el in buttonGroup"
@ -49,22 +49,22 @@
</div> </div>
</div> </div>
<el-tag <el-tag
v-for="el in tags" v-for="(el, ind) in item.storeType"
:key="el.label" :key="ind"
:type="el.type" :type="el"
size="small" size="small"
>{{ el.label }}</el-tag >{{ el == 1 ? "特卖" : el == 2 ? "鱼小铺" : "普通" }}</el-tag
> >
</div> </div>
</div> </div>
<el-descriptions :column="1" :size="size" :style="blockMargin"> <el-descriptions :column="1" :size="size" :style="blockMargin">
<el-descriptions-item <el-descriptions-item
v-for="(el, index) in descriptions" v-for="(el, index) in item.descriptions"
:key="index" :key="index"
:label="el.label" :label="el.label"
:class-name="el.cssName" :class-name="el.cssName"
:label-class-name="el.cssName" :label-class-name="el.cssName"
>kooriookami</el-descriptions-item >{{ el.value }}</el-descriptions-item
> >
</el-descriptions> </el-descriptions>
</div> </div>
@ -82,6 +82,7 @@
:ruleForm="CreateStore.ruleForm" :ruleForm="CreateStore.ruleForm"
:ruleFormList="CreateStore.ruleFormList" :ruleFormList="CreateStore.ruleFormList"
:rules="CreateStore.rules" :rules="CreateStore.rules"
:editText="CreateStore.editText"
@CreateStoreClose="CreateStoreClose" @CreateStoreClose="CreateStoreClose"
@submitForm="submitForm" @submitForm="submitForm"
></CreateStoreDialog> ></CreateStoreDialog>
@ -89,23 +90,42 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive } from "vue"; import { router } from "@/router.js";
import { ref, reactive, onMounted, watch, computed } from "vue";
import { Delete, Edit, Search, Share, Upload } from "@element-plus/icons-vue"; import { Delete, Edit, Search, Share, Upload } from "@element-plus/icons-vue";
import CreateStoreDialog from "./CreateStoreDialog/CreateStoreDialog.vue"; import CreateStoreDialog from "./CreateStoreDialog/CreateStoreDialog.vue";
import axioshooks from '@services/axioshooks.js' import {
save_shop,
const tags = ref([ list_shop,
{ type: "primary", label: "Tag 1" }, upload,
{ type: "primary", label: "Tag 1" }, update_shop,
{ type: "primary", label: "Tag 1" }, delById,
]); } from "@/api/xyshop";
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
const route = useRoute();
const CreateStoreDialogVisible = ref(route.query.CreateStoreDialogVisible);
const get_win_width = computed(() => {
const xl = window.innerWidth > 1920 ? 4 : 6;
return xl;
});
const buttonGroup = ref([ const buttonGroup = ref([
{ {
type: "primary", type: "primary",
label: "编辑", label: "编辑",
icon: Edit, icon: Edit,
handler: (item) => { handler: (item) => {
operation("edit", item); CreateStore.CreateStoreTitle = "编辑店铺";
CreateStore.editText = "编辑";
CreateStore.CreateStoreDialogVisible = true;
CreateStore.ruleForm = {
id: item.id,
xyName: item.xyName,
shopDescr: item.shopDescr,
};
CreateStore.ruleFormList.find(
(e) => e.type == "UploadImage"
).fileImgList = [{ url: item.lcon }];
}, },
}, },
{ {
@ -113,164 +133,138 @@ const buttonGroup = ref([
label: "删除", label: "删除",
icon: Delete, icon: Delete,
handler: (item) => { handler: (item) => {
operation("delete", item); delById(item.id).then((res) => {
if (res.code == "200") {
get_list_shop();
}
});
}, },
}, },
]); ]);
const descriptions = ref([
{ label: "闲鱼号:" },
{ label: "昵称:" },
{ label: "授权:", cssName: "active" },
{ label: "备注:" },
]);
const CreateStore = reactive({ const CreateStore = reactive({
ruleForm: { ruleForm: {
class_id: "23", xyName: "",
business_line: [ shopDescr: "",
{ lcon: "",
abl_id: "",
customer_id: "",
},
],
account: "",
quality_inspector: "",
contact_name: "",
inspection_signature: "",
inspection_avatar: "",
inspection_position: "",
inspection_positions: [],
}, },
ruleFormList: [ ruleFormList: [
{ {
type: "el-input", type: "el-input",
label: "账号名称", label: "店铺名称",
params: "account", params: "xyName",
prop: "account", prop: "xyName",
clearable: true, clearable: true,
placeholder: "请输入账号名称", placeholder: "请输入店铺名称",
},
{
type: "el-input",
label: "质检师签名",
params: "inspection_signature",
prop: "inspection_signature",
clearable: true,
placeholder: "请输入质检师签名",
},
{
type: "el-input",
label: "质检师职位",
params: "inspection_position",
prop: "inspection_position",
clearable: true,
placeholder: "请输入质检师职位",
}, },
{ {
type: "UploadImage", type: "UploadImage",
label: "质检师头像", label: "店铺图片",
params: "inspection_avatar", params: "inspection_avatar",
// prop: "inspection_avatar",
limit: 1, limit: 1,
multiple: true,
fileImgList: [], fileImgList: [],
handler: (file,filelist) => { onSuccessFiles: (files) => {
console.log(file,filelist,"file,filelist"); upload({ file: files.raw }).then((res) => {
return if (res.code === "200") {
CreateStore.ruleFormList.find( CreateStore.ruleForm.lcon = res.data;
(e) => e.label === "质检师头像" ElMessage.success("上传成功");
).fileImgList = files; }
CreateStore.ruleForm.inspection_avatar = files; });
}, },
}, },
{
type: "el-select",
label: "城市",
params: "",
prop: "",
clearable: true,
placeholder: "请选择城市",
options: [],
},
{
type: "el-select",
label: "商品业务模式",
params: "",
prop: "",
clearable: true,
placeholder: "请选择闲鱼商品业务模式",
options: [],
},
{
type: "el-checkbox-group",
label: "保障服务",
params: "inspection_positions",
prop: "",
clearable: true,
placeholder: "请选择保障服务",
options: [
{
label: "闲鱼-是否支持七天无理由",
value: "1",
},
{
label: "闲鱼-是否支持描述不符包邮退",
value: "2",
},
{
label: "闲鱼-是否支持 极速发货-24小时",
value: "3",
},
],
},
{ {
type: "el-input", type: "el-input",
label: "备注", label: "备注",
params: "", params: "shopDescr",
prop: "", prop: "shopDescr",
clearable: true, clearable: true,
placeholder: "请输入备注", placeholder: "请输入备注",
}, },
], ],
rules: { rules: {
account: [{ trigger: "blur", required: true, message: "请输入内容" }], xyName: [{ trigger: "blur", required: true, message: "请输入店铺名称" }],
inspection_signature: [
{ trigger: "change", required: true, message: "请输入质检师签名" },
],
inspection_avatar: [
{
validator: "",
required: true,
message: "请上传质检师头像",
},
],
inspection_position: [
{ trigger: "change", required: true, message: "请输入质检师职位" },
],
account: [{ trigger: "change", required: true, message: "请输入95分账号" }],
contact_name: [
{ trigger: "change", required: true, message: "请输入联系人" },
],
}, },
CreateStoreDialogVisible: false, CreateStoreDialogVisible: false,
CreateStoreTitle: "", CreateStoreTitle: "",
editText: "",
}); });
const operation = (status, item) => { const operation = (status, item) => {
if (status === "create") { if (status === "create") {
CreateStore.CreateStoreTitle = "创建店铺"; CreateStore.CreateStoreTitle = "创建店铺";
CreateStore.editText = "授权店铺";
CreateStore.ruleForm = {
xyName: "",
shopDescr: "",
lcon: "",
};
CreateStore.ruleFormList.find((e) => e.type == "UploadImage").fileImgList =
[];
CreateStore.CreateStoreDialogVisible = true; CreateStore.CreateStoreDialogVisible = true;
} else if (status === "edit") { } else if (status === "publish") {
console.log(status, item, "pkpkpkppkp"); router.push({
} else { path: "/NewlyBuiltGoods",
console.log("删除", item, "pkpkpkppkp"); });
} }
}; };
const CreateStoreClose = () => { const CreateStoreClose = () => {
CreateStore.CreateStoreDialogVisible = false; CreateStore.CreateStoreDialogVisible = false;
}; };
const submitForm = () => { const submitForm = () => {
console.log(CreateStore.ruleForm.account, "ruleFormruleForm"); if (CreateStore.editText == "授权店铺") {
save_shop(CreateStore.ruleForm).then((res) => {
if (res.code === "200") {
window.open(res.data);
get_list_shop();
CreateStoreClose();
}
});
} else {
update_shop(CreateStore.ruleForm).then((res) => {
if (res.code === "200") {
get_list_shop();
CreateStoreClose();
}
});
}
}; };
const store_list = ref({});
//
const get_list_shop = () => {
list_shop().then((res) => {
if (res.code === "200") {
store_list.value = res.data;
res.data.forEach((item) => {
item.descriptions = [
{ label: "闲鱼号:", value: item.xyAccount },
{ label: "昵称:", value: item.xyName },
{
label: "授权:",
cssName: "active",
value:
Math.ceil(
(new Date(item.expireTime) - new Date()) / (1000 * 60 * 60 * 24)
) + "天",
},
{ label: "备注:", value: item.shopDescr },
];
});
}
});
};
onMounted(() => {
CreateStore.CreateStoreDialogVisible = route.query.CreateStoreDialogVisible;
get_list_shop();
});
watch(
() => route.query.CreateStoreDialogVisible,
(val) => {
if (val) {
CreateStore.CreateStoreDialogVisible = CreateStoreDialogVisible;
}
}
);
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>

View File

@ -50,21 +50,21 @@ export default defineConfig((command, mode) => {
errors: true, errors: true,
}, },
host: '0.0.0.0', host: '0.0.0.0',
proxy: { // proxy: {
[process.env.VUE_APP_BASE_API]: { // [process.env.VUE_APP_BASE_API]: {
//这里是公共部分,在调用接口时后面接不相同的部分 // //这里是公共部分,在调用接口时后面接不相同的部分
target: process.env.VUE_APP_BASE_API, //修改后台接口地址 // target: process.env.VUE_APP_BASE_API, //修改后台接口地址
changeOrigin: true, //开启跨域 // // changeOrigin: true, //开启跨域
pathRewrite: { // pathRewrite: {
//重命名 // //重命名
["^" + process.env.VUE_APP_BASE_API]: "", // ["^" + process.env.VUE_APP_BASE_API]: "",
}, // },
}, // },
'^/api': { // '^/api': {
target: 'http://dev-erp-api.xtkj99.com:7890', // target: 'http://dev-erp-api.xtkj99.com:7890',
changeOrigin: true // changeOrigin: true
} // }
}, // },
disableHostCheck: true, disableHostCheck: true,
}, },
resolve: { resolve: {