daShangDao_miniProgram/components/IsbnUploadForm.vue
2026-06-15 16:37:57 +08:00

1776 lines
48 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="form-container">
<view v-if="currentTab === 'isbn'" class="form-content">
<view class="view-container">
<warehouse-selector :initialStorage="selectedStorage" :initialWarehouse="selectedWarehouse"
@label-click="navigateBack" @storage-selected="handleStorageSelected" ref="warehouseSelector"
style="flex: 0.47"></warehouse-selector>
<view class="view-item">
<view class="label">ISBN</view>
<view class="input-group">
<view class="input-container">
<input class="scan-input" v-model="scanResult" placeholder="请点击扫码"
:disabled="fileList1.length > 0" />
<view class="scan-btn" :class="{ 'scan-btn-disabled': isScanning || fileList1.length > 0 }"
@click="startScanning"
:style="(isScanning || fileList1.length > 0) ? 'opacity: 0.5;' : ''">
<text>{{ isScanning ? '扫描中...' : '扫码' }}</text>
</view>
<view class="scan-btn" @click="searchByIsbn"
:class="{ 'scan-btn-disabled': fileList1.length > 0 }"
:style="fileList1.length > 0 ? 'opacity: 0.5;' : ''">
<text>搜索</text>
</view>
</view>
</view>
</view>
</view>
<view class="view-container">
<view class="view-item">
<view class="label">书名</view><input class="input" v-model="formData.bookName" placeholder="请输入书名"
:disabled="fileList1.length > 0" />
</view>
</view>
<book-condition-select ref="conditionSelect" @change="onConditionChange"></book-condition-select>
<price-stock-control :price.sync="value4" :stock.sync="value3" @priceChange="onPriceChange"
@stockChange="onStockChange" ref="priceStockControl" />
<camera-upload v-model="fileList1" :maxCount="9" :isbn="scanResult" :bookName="formData.bookName"
@input="handleFileChange" @camera-status-change="handleCameraStatusChange"
@upload-status-change="handleUploadStatusChange"></camera-upload>
<view class="view-container">
<view class="view-item">
<view class="label">市场竞争</view>
</view>
<view class="tag-input-group">
<text v-for="(item, index) in marketTags" :key="index" class="market-tag">
[{{ item.label }}{{ item.value }}]
</text>
</view>
</view>
<on-sale-products :initialOnSaleProducts="onSaleProducts"
:initialDisplayOnSaleProducts="displayOnSaleProducts" :initialCompareType="compareType"
:isbn="scanResult" :bookName="formData.bookName" @compare-type-change="handleCompareTypeChange"
@filters-applied="handleFiltersApplied" @filters-reset="handleFiltersReset"
@products-updated="handleProductsUpdated" ref="onSaleProductsComponent" />
<view class="view-container" style="margin-top: 40rpx; margin-bottom: 200rpx;">
<view class="view-item updateBook" @click="getBookRecords" style="display: flex; align-items: center;">
<view class="blue-block"></view>
<text class="general-label" style="background: none; padding: 0;">上书记录</text>
</view>
</view>
<view class="form-item fixed-bottom" v-show="showSubmitButton">
<button type="primary" @click="submitForm" class="submit-btn"
:disabled="isSubmitting || isUploading">{{ isSubmitting ? '正在提交...' : (isUploading ? '图片上传中...' : '提交') }}</button>
<u-popup class="form-popup" :show="popupDialog.show" mode="center">
<view class="popupContentBox">{{ popupDialog.title }}</view>
<view class="popupContentBox">{{ popupDialog.content }}</view>
<view class="c_box_">
<image :src="popupDialog.imgSrc" mode="aspectFill" class="popup-image"></image>
</view>
<view class="select-container">
<view class="custom-select" @click="popupDialog.showPicker = true">
<text>{{ popupDialog.selectedSeries || '请选择' }}</text>
</view>
</view>
<u-picker :show="popupDialog.showPicker" :columns="[popupDialog.seriesOptions]"
@confirm="onSeriesConfirm" @cancel="popupDialog.showPicker = false"></u-picker>
<view class="button-group">
<view class="btn cancel-btn" @click="onPopupCancel">
<text>{{ popupDialog.cancelText }}</text>
</view>
<view class="btn confirm-btn" @click="onPopupConfirm">
<text>{{ popupDialog.confirmText }}</text>
</view>
</view>
</u-popup>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from 'vuex'
// Vuex 模块拆分后使用命名空间访问
import CryptoJS from 'crypto-js';
import CameraUpload from '@/components/CameraUpload.vue';
import PriceStockControl from '@/components/PriceStockControl.vue';
import BookConditionSelect from '@/components/BookConditionSelect.vue';
import WarehouseSelector from '@/components/WarehouserSelector.vue';
import * as selectBookImage from '@/service/selectBookImage.js';
import BookProductList from '@/components/BookProductList.vue';
import * as bookRecords from '@/service/bookRecords.js';
import {
uploadFile
} from '@/utils/upload.js';
import {
checkMemberBooksCount
} from '@/components/MemberBookCheck.js';
export default {
name: 'IsbnUploadForm',
props: {
selectedWarehouse: {
type: Object,
default: null
}
},
computed: {
...mapState('price', ['priceMode', 'priceType', 'averageRange', 'freight', 'minValue']),
...mapState('warehouse', ['selectedPosition'])
},
components: {
'price-stock-control': PriceStockControl,
'camera-upload': CameraUpload,
'book-condition-select': BookConditionSelect,
'on-sale-products': BookProductList,
'warehouse-selector': WarehouseSelector,
},
created() {
this.$selectBookImage = selectBookImage;
},
data() {
return {
lowestBookPrice: 0,
lowestTotalPrice: 0,
currentTab: 'isbn',
scanResult: null,
showSubmitButton: true,
isScanning: false,
isSubmitting: false,
isUploading: false,
value4: 1.00,
value3: 1,
fileList1: [],
uploadedImages: [],
selectedStorage: '',
warehouse: '',
shelf: '',
location: '',
compareType: 'isbn',
onSaleProducts: [],
displayOnSaleProducts: [],
soldProducts: [],
publisherOptions: [],
formattedData: [],
selectedCondition: '',
selectedConditionName: '',
authorOptions: [],
press: '',
author: '',
pubDateText: '',
filteredOnSaleProducts: [],
filteredSoldProducts: [],
isFiltered: false,
publisherAuthorMap: new Map(),
authorPublisherMap: new Map(),
selectedStorage: '',
shelves: [],
locations: [],
LocalWarehouse: this.selectedWarehouse,
selectedSheId: null,
selectedFreId: null,
formData: {
isbn: '',
sku: '',
title: '',
art_no: '',
more: '',
bookName: '',
},
columns: [
[],
[],
[]
],
warehouseShelvesData: {},
shelfLocationsData: {},
marketTags: [{
label: '在售:',
value: 0
},
{
label: '旧:',
value: 0
},
{
label: '新:',
value: 0
},
{
label: '已售:',
value: 0
}
],
popupDialog: {
show: false,
title: '',
content: '',
confirmText: '',
cancelText: '',
imgSrc: '',
count: 0,
subFormData: null,
showPicker: false,
selectedSeries: '',
seriesOptions: ['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
},
hasShownUploadMessage: false,
categoryList: [],
categoryOptions2: [],
categoryOptions3: [],
categoryLevel1: null,
categoryLevel2: null,
categoryLevel3: null,
selectedCategoryId: '',
categoryIndexes: [],
maxCategoryLevel: 6,
categoryPathText: '',
categoryColumns: [],
categoryLevels: [],
kfzBookPic: '',
};
},
watch: {
selectedWarehouse: {
handler(newVal) {
if (newVal) {
this.columns[0] = [newVal.name];
this.fetchShelves(newVal.id).then(shelves => {
if (shelves.length > 0) {
this.columns[1] = shelves.map(item => item.code);
this.fetchLocations(shelves[0].id).then(locations => {
this.columns[2] = locations.map(item => item.code);
});
} else {
this.columns[1] = [];
this.columns[2] = [];
}
});
this.selectedStorage = '';
this.warehouse = '';
this.shelf = '';
this.location = '';
}
},
immediate: true
},
displayOnSaleProducts: {
handler(newProducts) {
if (newProducts && newProducts.length > 0) {
this.lowestBookPrice = Math.min(...newProducts.map(p => parseFloat(p.bookPrice) || 0));
this.lowestTotalPrice = Math.min(...newProducts.map(p => parseFloat(p.totalPrice) || 0));
this.calculateReferencePrice();
}
},
immediate: true
},
priceMode: {
handler() {
this.calculateReferencePrice();
}
},
priceType: {
handler() {
this.calculateReferencePrice();
}
},
averageRange: {
handler() {
this.calculateReferencePrice();
}
},
freight: {
handler() {
this.calculateReferencePrice();
}
},
minValue: {
handler() {
this.calculateReferencePrice();
}
},
selectedPosition: {
handler() {
this.calculateReferencePrice();
}
}
},
methods: {
loadStorageSelection() {
try {
if (!this.selectedWarehouse || !this.selectedWarehouse.id) {
return;
}
const storageKey = `selectedStorageData_${this.selectedWarehouse.id}`;
const storageData = uni.getStorageSync(storageKey);
if (storageData) {
this.selectedStorage = storageData.selectedStorage || '';
this.warehouse = storageData.warehouse || '';
this.shelf = storageData.shelf || '';
this.location = storageData.location || '';
this.selectedSheId = storageData.selectedSheId || null;
this.selectedFreId = storageData.selectedFreId || null;
this.$nextTick(() => {
if (this.$refs.warehouseSelector) {
const formattedData = {
storage: storageData.selectedStorage,
warehouse: storageData.warehouse,
shelf: storageData.shelf,
location: storageData.location,
shelfId: storageData.selectedSheId,
locationId: storageData.selectedFreId
};
this.$refs.warehouseSelector.updateSelectedStorage(formattedData);
}
});
}
} catch (error) {
console.error('加载货区选择状态失败:', error);
}
},
async resetData() {
console.log('ISBN组件resetData方法开始执行');
try {
const currentWarehouse = this.warehouse;
const currentShelf = this.shelf;
const currentLocation = this.location;
const currentSelectedStorage = this.selectedStorage;
this.scanResult = '';
this.kfzBookPic = '';
this.formData = {
isbn: '',
sku: '',
title: '',
art_no: '',
more: '',
bookName: '',
recommendation: ''
};
this.value4 = 1.00;
this.value3 = 1;
this.fileList1 = [];
this.uploadedImages = [];
this.hasShownUploadMessage = false;
this.isUploading = false;
this.marketTags = [{
label: '在售:',
value: 0
},
{
label: '旧:',
value: 0
},
{
label: '新:',
value: 0
},
{
label: '已售:',
value: 0
}
];
this.warehouse = currentWarehouse;
this.shelf = currentShelf;
this.location = currentLocation;
this.selectedStorage = currentSelectedStorage;
if (this.$refs.onSaleProductsComponent) {
this.$refs.onSaleProductsComponent.updateProducts([]);
this.$refs.onSaleProductsComponent.setCompareType('isbn');
}
if (this.$refs.conditionSelect) {
this.$refs.conditionSelect.resetSelection();
}
if (this.$refs.priceStockControl) {
this.$refs.priceStockControl.reset();
}
this.categoryIndexes = [];
this.categoryPathText = '';
this.selectedCategoryId = '';
this.categoryLevels = [];
this.initCategoryPicker();
console.log('ISBN组件resetData方法执行完成');
} catch (error) {
console.error('重置数据时发生错误:', error);
return Promise.reject(error);
}
},
async fetchCategoryData() {
try {
const cookies = uni.getStorageSync('cookies');
if (!cookies) {
console.error('获取分类失败: 未找到cookies');
return;
}
const res = await uni.request({
url: 'https://api.buzhiyushu.cn/api/kongfz/getCategory',
method: 'GET',
data: {
token: cookies
},
header: {
'Content-Type': 'application/json'
}
});
const responseData = Array.isArray(res) ? res[1].data : res.data;
if (responseData && responseData.successResponse) {
this.categoryList = responseData.successResponse;
this.initCategoryPicker();
}
} catch (error) {
console.error('获取分类数据异常:', error);
}
},
handleCameraStatusChange(isCameraOpen) {
this.showSubmitButton = !isCameraOpen;
},
async handleCompareTypeChange(payload) {
this.compareType = payload.type;
if (payload.type === 'isbn') {
this.scanResult = payload.value;
} else {
this.formData.bookName = payload.value;
}
const keyword = payload.type === 'isbn' ? this.scanResult : this.formData.bookName;
await this.fetchOnSaleProducts(keyword);
},
handleStorageSelected(data) {
this.selectedStorage = data.storage;
this.warehouse = data.warehouse;
this.shelf = data.shelf;
this.location = data.location;
this.selectedSheId = data.shelfId;
this.selectedFreId = data.locationId;
uni.setStorageSync('warehouseId', this.selectedWarehouse.id);
uni.setStorageSync('shelfId', data.shelfId);
uni.setStorageSync('locationId', data.locationId);
},
handleFiltersApplied(filteredProducts) {
this.filteredOnSaleProducts = filteredProducts;
this.isFiltered = true;
},
handleFiltersReset() {
this.isFiltered = false;
},
handleProductsUpdated(products) {
this.displayOnSaleProducts = products;
this.calculateReferencePrice();
},
async fetchOnSaleProducts(keyword) {
try {
const conditionValue = uni.getStorageSync("conditionValue");
const sortType = 7;
let cookies = uni.getStorageSync('UserInfoCookies');
if (!cookies) {
cookies = uni.getStorageSync('cookies');
}
if (!cookies) {
uni.showToast({
title: '请先在设置页面登录孔网账号',
icon: 'none',
duration: 2500
});
return;
}
const mockData = await this.$selectBookImage.fetchOnSaleProducts(keyword, sortType, conditionValue,
cookies);
const blockedShopsStr = uni.getStorageSync('blockedShops') || '';
const blockedShops = blockedShopsStr.split(';').filter(shop => shop.trim() !== '');
const filteredData = mockData.filter(product => {
return !blockedShops.some(shop => product.shopName && product.shopName.includes(shop
.trim()));
});
this.onSaleProducts = [...filteredData];
if (this.$refs.onSaleProductsComponent) {
this.$refs.onSaleProductsComponent.updateProducts(this.onSaleProducts);
}
this.calculateReferencePrice();
} catch (error) {
console.error('获取在售商品信息失败:', error);
}
},
onConditionChange(index, conditionName) {
this.selectedConditionName = conditionName;
},
handleFileChange(newFileList) {
this.fileList1 = newFileList;
if (this.fileList1.length > 0 && (!this.hasShownUploadMessage)) {
uni.showToast({
title: '已上传图片ISBN和书名不可修改',
icon: 'none',
duration: 2000
});
this.hasShownUploadMessage = true;
} else if (this.fileList1.length === 0) {
this.hasShownUploadMessage = false;
}
this.isUploading = newFileList.some(file => file.status === 'uploading');
},
async getBookRecords() {
try {
const phoneNumber = uni.getStorageSync('phoneNumber');
if (!phoneNumber) {
uni.showToast({
title: '请先登录',
icon: 'none',
duration: 2500
});
return;
}
uni.showLoading({
title: '加载中...'
});
try {
const records = await bookRecords.fetchBookRecords(phoneNumber);
if (!records || records.length === 0) {
uni.showToast({
title: '暂无上书记录',
icon: 'none',
duration: 2500
});
return;
}
uni.navigateTo({
url: '/pkgUser/book-records',
success: (res) => {
res.eventChannel.emit('bookRecordsData', {
records: records
});
}
});
} finally {
uni.hideLoading();
}
} catch (error) {
console.error('获取上书记录失败:', error);
}
},
onSeriesConfirm(e) {
this.popupDialog.selectedSeries = e.value[0];
this.popupDialog.showPicker = false;
},
async submitForm() {
const lastSubmitTime = uni.getStorageSync('lastSubmitTime');
const currentTime = Date.now();
if (lastSubmitTime) {
const timeDiff = currentTime - lastSubmitTime;
const twoHours = 2 * 60 * 60 * 1000;
if (timeDiff > twoHours) {
uni.showToast({
title: '登录已过期,请重新登录',
icon: 'none',
duration: 2000
});
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/index'
});
}, 2000);
return;
}
}
uni.setStorageSync('lastSubmitTime', currentTime);
const canUpload = await checkMemberBooksCount();
if (!canUpload) {
return;
}
if (this.isSubmitting) {
return;
}
this.isSubmitting = true;
const warehouse = this.warehouse;
const shelf = this.shelf;
const location = this.location;
const userId = uni.getStorageSync("userId");
if (!this.scanResult) {
uni.showToast({
title: '请扫码获取ISBN',
icon: 'none',
duration: 2500
});
this.isSubmitting = false;
return;
}
if (!this.formData.bookName) {
uni.showToast({
title: '请输入书名',
icon: 'none',
duration: 2500
});
this.isSubmitting = false;
return;
}
if (!warehouse && !shelf && !location) {
uni.showToast({
title: '请选择仓库/货架/货位',
icon: 'none',
duration: 2500
});
this.isSubmitting = false;
return;
}
const selectedCondition = this.$refs.conditionSelect.getSelectedCondition();
if (!selectedCondition) {
uni.showToast({
title: '请选择品相',
icon: 'none',
duration: 2500
});
this.isSubmitting = false;
return;
}
if (this.fileList1.length > 0) {
if (this.fileList1.length > 0) {
const temporaryImages = [];
this.fileList1.forEach((file, index) => {
if (file.url && (file.url.startsWith('file://') ||
file.url.startsWith('blob:') ||
file.url.startsWith('wxfile://') ||
file.url.indexOf('tmp') !== -1)) {
temporaryImages.push(index + 1);
}
});
if (temporaryImages.length > 0) {
uni.showToast({
title: `${temporaryImages.join('、')}张图片上传失败,请重新拍照,若仍然失败请联系管理员!`,
icon: 'none',
duration: 4000
});
this.isSubmitting = false;
return;
}
}
try {
uni.showLoading({
title: '正在上传图片...'
});
this.isUploading = true;
for (let i = 0; i < this.fileList1.length; i++) {
const file = this.fileList1[i];
if (file.status === "ready") {
this.fileList1.splice(i, 1, {
...file,
status: "uploading",
message: "上传中"
});
try {
const result = await this.uploadFilePromise(file.url, i);
this.fileList1.splice(i, 1, {
...file,
status: "success",
message: "",
url: result,
num: (i + 1).toString()
});
} catch (error) {
console.error('图片上传失败:', error);
this.fileList1.splice(i, 1, {
...file,
status: "error",
message: "上传失败",
errorMessage: `${i + 1}张图片上传失败`
});
uni.showModal({
title: '图片上传失败',
content: `${i + 1}张图片上传失败,请检查网络连接后重新上传`,
showCancel: false,
confirmText: '我知道了'
});
this.isSubmitting = false;
this.isUploading = false;
uni.hideLoading();
return;
}
}
}
this.isUploading = false;
uni.hideLoading();
} catch (error) {
console.error('图片上传过程出错:', error);
uni.hideLoading();
uni.showToast({
title: '图片上传失败',
icon: 'none',
duration: 2500
});
this.isSubmitting = false;
this.isUploading = false;
return;
}
}
const invalidImages = [];
this.fileList1.forEach((img, index) => {
if (
img.url &&
(
img.url.startsWith('file://') ||
img.url.startsWith('blob:') ||
img.url.startsWith('wxfile://') ||
img.url.indexOf('tmp') !== -1
)
) {
invalidImages.push({
...img,
index
});
}
});
if (invalidImages.length > 0) {
console.error('发现临时路径图片:', invalidImages);
const problemImageNumbers = invalidImages
.map(img => img.index + 1)
.join('、');
const errorMessage = `${problemImageNumbers}张图片上传异常,请重新上传这些图片`
uni.showModal({
title: '图片上传异常',
content: errorMessage,
showCancel: false,
confirmText: '我知道了',
success: () => {
this.highlightProblemImages(invalidImages);
}
});
this.isSubmitting = false;
return;
}
const sellCountTag = this.marketTags.find(tag => tag.label === '在售:');
const buyCountTag = this.marketTags.find(tag => tag.label === '已售:');
const sellCount = sellCountTag ? sellCountTag.value : 0;
const buyCount = buyCountTag ? buyCountTag.value : 0;
const formData = {
barcode: this.scanResult,
userId: userId,
name: this.formData.bookName,
recommendation: this.formData.recommendation,
conditionCode: selectedCondition.name,
price: this.value4 * 100,
inventory: this.value3 || 1,
files: this.fileList1,
marketTags: this.marketTags,
sellCount: sellCount,
buyCount: buyCount,
author: this.author,
fixPrice: this.fixPrice * 100,
selectedStorage: this.selectedStorage,
depotName: this.warehouse,
shelvesName: this.shelf,
freightName: this.location,
phoneNumber: uni.getStorageSync('phoneNumber'),
passWord: uni.getStorageSync('password'),
tenantId: uni.getStorageSync('tenantId'),
userName: uni.getStorageSync('userName'),
categoryId: this.selectedCategoryId || ''
};
uni.request({
url: 'https://api.buzhiyushu.cn/zhishu/shopGoods/repeatBook',
method: 'POST',
data: formData,
header: {
'Content-Type': 'application/json'
},
success: (res) => {
if (res.data.data && res.data.data.count != 0) {
const bookName = res.data.data && res.data.data.name ? res.data.data.name
.trim() :
'';
const md5Hash = CryptoJS.MD5(bookName).toString();
const firstLetter = bookName ? md5Hash.charAt(0).toUpperCase() : '';
const imagePath = res.data.data && res.data.data.image ? res.data.data.image :
'';
const fullImageUrl =
`https://img.buzhiyushu.cn/zhishu1/${firstLetter}/${imagePath}`;
const count = res.data.data && res.data.data.count ? res.data.data.count : 0;
const allLetters = ['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N'
];
const startIndex = count > 0 ? count - 1 : 0;
if (startIndex >= 0 && startIndex < allLetters.length) {
this.popupDialog.seriesOptions = allLetters.slice(startIndex);
this.popupDialog.selectedSeries = this.popupDialog.seriesOptions[0];
}
this.popupDialog.title = '提示'
this.popupDialog.content = '请仔细核对此书是否为套装书,一号多书等情况?请选择(否:增加库存 是:新增书籍)'
this.popupDialog.confirmText = '是'
this.popupDialog.cancelText = '否'
this.popupDialog.imgSrc = fullImageUrl
this.popupDialog.show = true
this.popupDialog.count = count || 0
this.popupDialog.subFormData = formData
} else {
this.submitToServer(formData);
}
},
fail: (err) => {
console.error('检查重复书籍失败:', err);
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none',
duration: 2500
});
this.isSubmitting = false;
}
});
},
onPopupConfirm() {
this.popupDialog.subFormData.series = this.popupDialog.selectedSeries;
this.submitToServer(this.popupDialog.subFormData);
this.popupDialog.show = false
},
onPopupCancel() {
this.submitToServer(this.popupDialog.subFormData);
this.popupDialog.show = false
},
submitToServer(formData) {
uni.request({
url: 'https://api.buzhiyushu.cn/zhishu/shopGoods/submit',
// url: 'https://localhost:8080/zhishu/shopGoods/submit',
method: 'POST',
data: formData,
header: {
'Content-Type': 'application/json'
},
complete: () => {
this.isSubmitting = false;
},
success: (res) => {
const responseData = res.data.data;
const idsToPass = {
depotId: responseData.depotId,
freightId: responseData.freightId,
goodsId: responseData.goodsId,
shelvesId: responseData.shelvesId,
userId: responseData.userId,
artNo: responseData.artNo,
};
this.syncBookToCenter(formData);
const newFormData = {
...formData,
...idsToPass
};
uni.request
url: 'https://newadmin.buzhiyushu.cn/zhishu/shopGoods/submit',
method: 'POST',
data: newFormData,
header: {
'Content-Type': 'application/json'
},
success: (newAdminRes) => {
console.log('newadmin API请求成功:', newAdminRes);
},
fail: (newAdminErr) => {
console.error('newadmin API请求失败:', newAdminErr);
}
});
this.formData = {
bookName: '',
recommendation: '',
};
this.scanResult = '';
this.kfzBookPic = '';
this.value4 = this.value4;
this.value3 = 1;
this.fileList1 = [];
this.uploadedImages = [];
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
});
if (this.$refs.onSaleProductsComponent) {
this.$refs.onSaleProductsComponent.setCompareType('isbn');
}
setTimeout(() => {
this.startScanning();
}, 800);
},
fail: (err) => {
console.error('请求失败:', err);
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none',
duration: 2500
});
}
});
},
syncBookToCenter(formData) {
const centerUrl = 'https://api.buzhiyushu.cn/zhishu/baseInfo/getXcxData';
// const centerUrl = 'http://localhost:8080/zhishu/baseInfo/getXcxData';
const centerData = {
barcode: formData.barcode,
name: formData.name,
price: formData.price,
author: formData.author,
publisher: this.press,
publishTime: this.pubDateText,
sellCount: formData.sellCount,
buyCount: formData.buyCount,
files: formData.files || [],
kfzBookPic: this.kfzBookPic
};
setTimeout(() => {
uni.request({
url: centerUrl,
method: 'POST',
data: centerData,
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log('选品中心同步成功:', res);
},
fail: (err) => {
console.error('选品中心同步失败:', err);
}
});
}, 300);
},
uploadFilePromise(url, index) {
return new Promise((resolve, reject) => {
const bookName = this.formData.bookName;
let isbn = this.scanResult;
if (!isbn || isbn.trim() === '') {
isbn = '';
for (let i = 0; i < 13; i++) {
isbn += Math.floor(Math.random() * 10);
}
}
const warehouseId = uni.getStorageSync('warehouseId');
const shelfId = uni.getStorageSync('shelfId');
const locationId = uni.getStorageSync('locationId');
const num = (index + 1).toString();
uni.uploadFile({
url: "https://xcx.uploadfile.yushutx.com/uploadImages",
filePath: url,
name: "file",
success: (res) => {
console.log('图片上传成功:', res);
const data = JSON.parse(res.data);
const urlData = JSON.parse(data.data);
const imageUrl = urlData.url || url;
this.uploadedImages.push({
url: imageUrl,
bookName: bookName,
isbn: isbn,
num: num,
warehouseId: warehouseId,
shelfId: shelfId,
locationId: locationId,
originalUrl: url
});
resolve(imageUrl);
},
fail: (err) => {
console.error('图片上传失败:', err);
reject(err);
}
});
});
},
highlightProblemImages(invalidImages) {
invalidImages.forEach(invalidImg => {
const index = this.fileList1.findIndex(file => file.url === invalidImg.originalUrl);
if (index !== -1) {
this.$set(this.fileList1[index], 'status', 'error');
this.$set(this.fileList1[index], 'errorMessage', '上传失败,请重新上传');
}
});
this.$forceUpdate();
},
async populateForm(data) {
this.formData.bookName = data.bookName;
this.fixPrice = data.fixPrice;
this.formData.recommendation = "权威认证 立即购买";
this.value = data.price;
this.value1 = data.stock;
this.formData.isbn = data.isbn;
const sellCount = data.sellCount;
const buyCount = data.buyCount;
if (data.condition) {
this.$refs.conditionSelect.setSelection(data.condition);
}
this.marketTags = this.marketTags.map(item => {
if (item.label === '在售:') {
return {
...item,
value: sellCount
};
} else if (item.label === '已售:') {
return {
...item,
value: buyCount
};
}
return item;
});
},
calculateReferencePrice() {
if (!this.displayOnSaleProducts || this.displayOnSaleProducts.length === 0) {
this.value4 = 1.00;
return;
}
let products = [...this.displayOnSaleProducts];
let priceField = 'totalPrice';
products.sort((a, b) => parseFloat(a[priceField]) - parseFloat(b[priceField]));
const shippingFee = this.freight;
const minValue = this.minValue;
const priceMode = uni.getStorageSync("current1");
const selectedPositionIndex = uni.getStorageSync("selectedPositionIndex");
switch (priceMode) {
case 0:
const positionIndex = this.selectedPosition || selectedPositionIndex || 0;
const validIndex = Math.min(positionIndex, products.length - 1);
const selectedTotal = parseFloat(products[validIndex].totalPrice);
this.lowestTotalPrice = parseFloat(products[0].totalPrice);
const lowestPrice = selectedTotal - shippingFee - 0.01;
if (lowestPrice <= minValue) {
this.value4 = minValue;
} else {
this.value4 = parseFloat(lowestPrice.toFixed(2));
}
break;
case 1:
let count = Math.min(this.averageRange, products.length);
let sum = 0;
for (let i = 0; i < count; i++) {
sum += parseFloat(products[i][priceField]);
}
const averagePrice = (sum / count) - shippingFee - 0.01;
if (averagePrice <= minValue) {
this.value4 = minValue;
} else {
this.value4 = parseFloat(averagePrice.toFixed(2));
}
break;
case 2:
this.value4 = parseFloat(products[0].totalPrice);
break;
}
},
navigateBack() {
uni.removeStorageSync('lastSelectedStorage');
uni.removeStorageSync('selectedWarehouse');
uni.removeStorageSync('lastSelectedShelf');
uni.removeStorageSync('lastSelectedLocation');
this.selectedStorage = '';
this.warehouse = '';
this.shelf = '';
this.location = '';
uni.navigateTo({
url: '/pages/warehouse/warehouse-select'
});
},
onPriceChange(value) {
this.value4 = value;
},
onStockChange(value) {
this.value3 = value;
},
async startScanning() {
const canUpload = await checkMemberBooksCount();
if (!canUpload) {
return;
}
if (this.fileList1.length > 0) {
uni.showToast({
title: '已上传图片不可修改ISBN',
icon: 'none',
duration: 2000
});
return;
}
if (this.isScanning) {
return;
}
const warehouse = this.warehouse;
const shelf = this.shelf;
const location = this.location;
if (!warehouse || !shelf || !location) {
uni.showToast({
title: '请完整选择仓库、货架和货位',
icon: 'none',
duration: 2500
});
return;
}
this.isScanning = true;
this.selectedStorage = `${warehouse} / ${shelf} / ${location}`;
uni.scanCode({
onlyFromCamera: true,
scanType: ['barcode'],
success: (res) => {
this.isScanning = false;
if (this.$refs.onSaleProductsComponent) {
this.$refs.onSaleProductsComponent.setCompareType('isbn');
}
if (res.result.length != 13) {
console.error('扫码失败:');
uni.showToast({
title: '扫码失败,请重试',
icon: 'none',
duration: 2500
})
} else {
this.scanResult = res.result;
this.fetchBookInfo(res.result);
}
},
fail: (err) => {
this.isScanning = false;
this.scanResult = '';
this.formData.bookName = '';
this.fileList1 = [];
this.marketTags = [{
label: '在售:',
value: 0
},
{
label: '旧:',
value: 0
},
{
label: '新:',
value: 0
},
{
label: '已售:',
value: 0
}
];
if (this.$refs.onSaleProductsComponent) {
this.$refs.onSaleProductsComponent.updateProducts([]);
}
this.onSaleProducts = [];
this.displayOnSaleProducts = [];
console.error('扫码失败:', err.errMsg);
uni.showToast({
title: '扫码失败,请重试',
icon: 'none',
duration: 2500
});
}
});
},
async searchByIsbn() {
const canUpload = await checkMemberBooksCount();
if (!canUpload) {
return;
}
if (this.fileList1.length > 0) {
uni.showToast({
title: '已上传图片不可修改ISBN',
icon: 'none',
duration: 2000
});
return;
}
if (!this.scanResult) {
uni.showToast({
title: '请输入ISBN',
icon: 'none',
duration: 2500
});
return;
}
if (this.scanResult.length != 13) {
uni.showToast({
title: 'ISBN格式不正确应为13位数字',
icon: 'none',
duration: 2500
});
return;
}
const warehouse = this.warehouse;
const shelf = this.shelf;
const location = this.location;
if (!warehouse || !shelf || !location) {
uni.showToast({
title: '请完整选择仓库、货架和货位',
icon: 'none',
duration: 2500
});
return;
}
this.selectedStorage = `${warehouse} / ${shelf} / ${location}`;
this.fetchBookInfo(this.scanResult);
},
async fetchBookInfo(isbn) {
console.log("扫描到ISBN:", isbn)
const cookie = uni.getStorageSync('UserInfoCookies');
console.log("cookie1111", cookie)
const newCookie = `PHPSESSID=${cookie}`;
this.isScanning = false;
try {
const res = await uni.request({
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/list',
method: 'GET',
data: {
dataType: 0,
keyword: isbn,
page: 1,
userArea: '13003000000'
},
header: {
'Cookie': newCookie,
},
});
const soldOutRes = await uni.request({
url: 'https://api.buzhiyushu.cn/xcx/getOnSaleGoods',
method: 'GET',
data: {
dataType: 1,
keyword: isbn,
cookie: cookie,
},
header: {
'Content-Type': 'application/json'
}
});
let bookPicRes = null;
try {
bookPicRes = await uni.request({
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/bookLib/keyword/list',
method: 'GET',
data: {
keyword: isbn,
},
header: {
'Cookie': newCookie,
'Content-Type': 'application/json'
},
});
} catch (bookPicError) {
console.warn('获取孔网图书官图失败,不影响主流程:', bookPicError);
bookPicRes = null;
}
uni.hideLoading();
console.log("在售响应:", res);
const responseData = Array.isArray(res) ? res[1].data : res.data;
console.log("已售响应", soldOutRes);
if (bookPicRes) {
console.log("图书条目响应:", bookPicRes);
}
const responseData1 = Array.isArray(res) ? soldOutRes[1].data.data.data : soldOutRes.data.data
.data;
this.kfzBookPic = '';
if (bookPicRes && Array.isArray(bookPicRes) && bookPicRes[1]?.data?.data?.itemResponse?.list?.[0]
?.imgUrlEntity?.bigImgUrl) {
this.kfzBookPic = bookPicRes[1].data.data.itemResponse.list[0].imgUrlEntity.bigImgUrl;
}
console.log("图书条目图片:", this.kfzBookPic || '未获取到');
if (responseData.errType === "102" || responseData1.errType === "102") {
uni.showToast({
title: '请登录或切换孔网账号后再进行扫码上书',
icon: 'none',
duration: 2500
});
return;
}
if (res[1].data.data.itemResponse.total != 0 && responseData && responseData.status === 1 &&
responseData.data) {
const buyCount = res[1].data.data.itemResponse.total;
const author = res[1].data.data.itemResponse.list[0].author;
const press = res[1].data.data.itemResponse.list[0].press;
const pubDateText = res[1].data.data.itemResponse.list[0].pubDateText
this.author = author || '';
this.press = press || '';
this.pubDateText = pubDateText || '';
let bookData = null;
let productList = [];
if (responseData.data.itemResponse && responseData.data.itemResponse.list) {
productList = responseData.data.itemResponse.list;
} else if (responseData.data.productList) {
productList = responseData.data.productList;
} else if (Array.isArray(responseData.data)) {
productList = responseData.data;
}
console.log("在售", responseData.data.itemResponse.pager.total)
if (productList && productList.length > 0) {
bookData = productList[0];
const data = {
bookName: bookData.bookName || bookData.title || bookData.name || '',
fixPrice: bookData.newBookMinPrice || bookData.price || bookData.minPrice || 1.00,
sellCount: responseData.data.itemResponse.pager.total,
buyCount: responseData1.data.itemResponse.pager.total,
condition: '',
};
this.bookInfo = data;
this.populateForm(data);
this.fetchOnSaleProducts(isbn);
return;
}
}
this.isScanning = false;
this.scanResult = '';
this.formData.bookName = '';
this.fileList1 = [];
this.marketTags = [{
label: '在售:',
value: 0
},
{
label: '旧:',
value: 0
},
{
label: '新:',
value: 0
},
{
label: '已售:',
value: 0
}
];
if (this.$refs.onSaleProductsComponent) {
this.$refs.onSaleProductsComponent.updateProducts([]);
}
this.onSaleProducts = [];
this.displayOnSaleProducts = [];
uni.showToast({
title: '暂无当前书籍信息,请使用(无ISBN-上传)上传该书籍',
icon: 'none',
duration: 2500
});
} catch (error) {
uni.hideLoading();
console.error('请求异常:', error);
uni.showToast({
title: '网络请求失败',
icon: 'none',
duration: 2500
});
}
},
handleUploadStatusChange(isUploading) {
console.log('文件上传状态变化:', isUploading ? '上传中' : '未上传');
this.isUploading = isUploading;
},
initCategoryPicker() {
this.categoryColumns = [];
this.categoryLevels = [];
this.categoryIndexes = [];
const level1Categories = (this.categoryList || []).filter(item => item.level === 1);
if (level1Categories.length === 0) {
this.categoryColumns = Array(this.maxCategoryLevel).fill([{
name: '暂无数据',
id: ''
}]);
this.categoryIndexes = Array(this.maxCategoryLevel).fill(0);
this.categoryPathText = '';
this.selectedCategoryId = '';
return;
}
this.categoryColumns[0] = level1Categories;
this.categoryIndexes[0] = 0;
let currentParent = level1Categories[0];
let currentLevel = 1;
this.categoryLevels[0] = currentParent;
while (currentLevel < this.maxCategoryLevel) {
const children = currentParent.children || [];
if (children.length === 0) {
break;
}
this.categoryColumns[currentLevel] = children;
this.categoryIndexes[currentLevel] = 0;
this.categoryLevels[currentLevel] = children[0];
currentParent = children[0];
currentLevel++;
}
while (this.categoryColumns.length < this.maxCategoryLevel) {
this.categoryColumns.push([{
name: '暂无数据',
id: ''
}]);
this.categoryIndexes.push(0);
this.categoryLevels.push({
name: '暂无数据',
id: ''
});
}
this.updateCategoryPathText();
this.updateSelectedCategoryId();
},
onCategoryColumnChange(e) {
const {
column,
value
} = e.detail;
this.categoryIndexes[column] = value;
this.categoryLevels[column] = this.categoryColumns[column][value];
if (column < this.maxCategoryLevel - 1) {
this.updateSubsequentColumns(column + 1);
}
this.updateCategoryPathText();
this.updateSelectedCategoryId();
},
updateSubsequentColumns(startColumn) {
const parentCategory = this.categoryLevels[startColumn - 1];
if (!parentCategory || !parentCategory.children || parentCategory.children.length === 0) {
for (let i = startColumn; i < this.maxCategoryLevel; i++) {
this.categoryColumns[i] = [{
name: '暂无数据',
id: ''
}];
this.categoryIndexes[i] = 0;
this.categoryLevels[i] = {
name: '暂无数据',
id: ''
};
}
return;
}
this.categoryColumns[startColumn] = parentCategory.children;
this.categoryIndexes[startColumn] = 0;
this.categoryLevels[startColumn] = parentCategory.children[0];
if (startColumn < this.maxCategoryLevel - 1) {
this.updateSubsequentColumns(startColumn + 1);
}
},
onCategoryChange(e) {
const values = e.detail.value;
this.categoryIndexes = [...values];
for (let i = 0; i < values.length; i++) {
if (this.categoryColumns[i] && this.categoryColumns[i][values[i]]) {
this.categoryLevels[i] = this.categoryColumns[i][values[i]];
}
}
this.updateCategoryPathText();
this.updateSelectedCategoryId();
},
updateCategoryPathText() {
const validLevels = this.categoryLevels.filter(level => level && level.name && level.name !== '暂无数据');
this.categoryPathText = validLevels.map(level => level.name).join(' / ');
},
updateSelectedCategoryId() {
const validLevels = this.categoryLevels.filter(level => level && level.id && level.id !== '');
if (validLevels.length === 0) {
this.selectedCategoryId = '';
return;
}
this.selectedCategoryId = validLevels[validLevels.length - 1].id;
},
async fetchShelves(depotId) {
try {
const response = await uni.request({
url: 'https://api.buzhiyushu.cn/shelves/shelves/sheNamelist',
data: {
depotId
}
});
const [err, res] = Array.isArray(response) ? response : [null, response];
if (!res?.data?.rows) {
console.error('获取货架数据失败,返回空数据');
return [];
}
return res.data.rows;
} catch (error) {
console.error('获取货架失败:', error);
return [];
}
},
async fetchLocations(sheId) {
if (!sheId) {
console.error('获取货位列表失败未提供货架ID');
return [];
}
try {
const response = await uni.request({
url: 'https://api.buzhiyushu.cn/freight/freight/freNamelist',
data: {
sheId
}
});
const [err, res] = Array.isArray(response) ? response : [null, response];
if (!res?.data?.rows) {
console.error('获取货位数据失败,返回空数据');
return [];
}
return res.data.rows;
} catch (error) {
console.error('获取货位失败:', error);
return [];
}
},
}
};
</script>
<style scoped>
.form-container {
padding-left: 10rpx;
background-color: #fff;
}
.view-container {
display: flex;
background-color: #fff;
margin-bottom: 20rpx;
overflow: hidden;
border-bottom: 1px solid #ccc;
}
.view-item {
flex: 1;
display: flex;
padding: 4rpx 0;
text-align: center;
color: #666;
position: relative;
}
.view-item-7 {
flex: 7 !important;
}
.view-item>.label {
display: inline;
padding: 13rpx;
text-align: center;
height: 40rpx;
line-height: 40rpx;
color: #000;
font-size: 28rpx;
background-color: #ccc;
border-top-left-radius: 10rpx;
border-bottom-left-radius: 10rpx;
}
.view-item>.input-group {
padding: 10rpx;
text-align: center;
width: 100%;
height: 40rpx;
line-height: 40rpx;
}
.view-item>.input-group>.input-container {
display: flex;
width: 100%;
height: 40rpx;
line-height: 40rpx;
}
.input-container {
flex: 1;
display: flex;
align-items: center;
position: relative;
}
.scan-input {
flex: 1;
height: 60rpx;
font-size: 23rpx;
}
.scan-btn {
background: #007AFF;
padding: 8rpx 20rpx;
border-radius: 20rpx;
color: white;
font-size: 24rpx;
margin-left: 10rpx;
}
.scan-btn-disabled {
pointer-events: none;
background-color: #cccccc !important;
color: #999 !important;
}
.view-item>.input {
padding: 10rpx 20rpx;
text-align: center;
width: 100%;
height: 40rpx;
line-height: 40rpx;
text-align: left;
font-size: 30rpx;
}
.tag-input-group {
display: flex;
flex-wrap: inherit;
gap: 20rpx;
margin-top: 15rpx;
}
.market-tag {
color: #999;
font-size: 29rpx;
margin-right: 12rpx;
font-weight: normal;
background: none;
border: none;
border-radius: 0;
padding: 0;
}
.blue-block {
width: 8rpx;
height: 32rpx;
background-color: #007AFF;
margin-right: 16rpx;
border-radius: 4rpx;
flex-shrink: 0;
align-self: center;
}
.general-label {
font-size: 28rpx;
color: #333;
font-weight: bold;
line-height: 32rpx;
display: flex;
align-items: center;
}
.updateBook {
padding: 0rpx 10rpx;
}
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
padding: 20rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
z-index: 999;
box-sizing: border-box;
}
.submit-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background-color: #007AFF;
color: #fff;
border-radius: 8rpx;
font-size: 32rpx;
}
.submit-btn:disabled {
background-color: #ccc;
opacity: 0.8;
}
.popupContentBox {
width: 600rpx;
padding: 50rpx;
}
.c_box_ {
width: 400rpx;
margin: 50rpx auto;
}
.popup-image {
width: 300rpx;
height: 300rpx;
margin: 20rpx auto;
display: block;
}
.select-container {
margin: 20rpx 0;
text-align: center;
}
.custom-select {
padding: 10rpx 20rpx;
background-color: #f5f5f5;
border-radius: 4rpx;
text-align: center;
cursor: pointer;
}
.custom-select text {
font-size: 28rpx;
color: #333;
}
.button-group {
display: flex;
align-items: center;
gap: 20rpx;
margin: 10rpx 0;
}
.btn {
flex: 1;
height: 80rpx;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
}
.cancel-btn {
background-color: #f0f0f0;
color: #666;
}
.confirm-btn {
background-color: #007AFF;
color: white;
}
.btn:active {
opacity: 0.8;
}
</style>