|
@@ -0,0 +1,599 @@
|
|
|
+<template>
|
|
|
+ <div class="price-editor">
|
|
|
+ <s-header :name="$t('device.modifyPricePage.title')" :noback="false" />
|
|
|
+ <div class="content-container">
|
|
|
+ <!-- 设备信息卡片 -->
|
|
|
+ <div class="device-card">
|
|
|
+ <div class="device-header">
|
|
|
+ <div class="header-indicator"></div>
|
|
|
+ <h3 class="device-name">
|
|
|
+ {{ $t("device.modifyPricePage.equipmentName") }}:{{
|
|
|
+ equipmentName
|
|
|
+ }}
|
|
|
+ </h3>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 商品列表卡片 -->
|
|
|
+ <div class="goods-card">
|
|
|
+ <!-- 操作头部 -->
|
|
|
+ <div class="card-header">
|
|
|
+ <div class="goods-count">
|
|
|
+ {{ $t("device.modifyPricePage.total") }}
|
|
|
+ <span class="highlight">{{ tableData.length }}</span>
|
|
|
+ {{ $t("device.modifyPricePage.goods") }}
|
|
|
+ </div>
|
|
|
+ <van-button icon="edit" @click="noticeClk" class="batch-btn">
|
|
|
+ {{ $t("device.modifyPricePage.batchModify") }}
|
|
|
+ </van-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 商品列表 -->
|
|
|
+ <div class="goods-list">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in tableData"
|
|
|
+ :key="index"
|
|
|
+ class="goods-item"
|
|
|
+ :class="{ 'off-shelf': item.shelfStatus === 0 }"
|
|
|
+ >
|
|
|
+ <!-- 左侧商品图片 -->
|
|
|
+ <div class="goods-image-container">
|
|
|
+ <van-image
|
|
|
+ class="goods-image"
|
|
|
+ :src="showSugerPhoto(item)"
|
|
|
+ fit="cover"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 中间商品信息 -->
|
|
|
+ <div class="goods-info">
|
|
|
+ <!-- 商品名称行 -->
|
|
|
+ <div class="name-row">
|
|
|
+ <template v-if="item.isEditName">
|
|
|
+ <van-field
|
|
|
+ v-model="item.productName"
|
|
|
+ class="name-input"
|
|
|
+ :border="false"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
+ </van-field>
|
|
|
+ <van-icon
|
|
|
+ name="success"
|
|
|
+ class="action-icon"
|
|
|
+ @click="updateProduct(item, 1)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <span class="goods-name">{{ item.productName }}</span>
|
|
|
+ <van-icon
|
|
|
+ name="edit"
|
|
|
+ class="name-edit-icon"
|
|
|
+ @click="item.isEditName = true"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 价格行 -->
|
|
|
+ <div class="price-row">
|
|
|
+ <template v-if="item.isEditPrice">
|
|
|
+ <van-field
|
|
|
+ type="number"
|
|
|
+ v-model="item.rmbPrice"
|
|
|
+ class="price-input"
|
|
|
+ :border="false"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
+ <template #extra>
|
|
|
+ <span class="currency-symbol">{{ currencySymbol }}</span>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ <van-icon
|
|
|
+ name="success"
|
|
|
+ class="action-icon"
|
|
|
+ @click="updateProduct(item, 2)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div class="price-display">
|
|
|
+ <span class="currency">{{ currencySymbol }}</span>
|
|
|
+ <span class="price">{{ item.rmbPrice }}</span>
|
|
|
+ </div>
|
|
|
+ <van-icon
|
|
|
+ name="edit"
|
|
|
+ class="action-icon"
|
|
|
+ @click="item.isEditPrice = true"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧开关控制 -->
|
|
|
+ <div class="shelf-control">
|
|
|
+ <van-switch
|
|
|
+ v-model="item.sellStatus"
|
|
|
+ :active-value="true"
|
|
|
+ :inactive-value="false"
|
|
|
+ size="22px"
|
|
|
+ active-color="#4d6add"
|
|
|
+ inactive-color="#dcdee0"
|
|
|
+ @change="updateProduct(item, 3)"
|
|
|
+ />
|
|
|
+ <span class="shelf-status">
|
|
|
+ {{
|
|
|
+ item.sellStatus ? $t("device.onShelf") : $t("device.offShelf")
|
|
|
+ }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 批量修改弹窗 -->
|
|
|
+ <kDialog
|
|
|
+ :isCloseForConfirm="false"
|
|
|
+ :dialogTitle="$t('device.modifyPricePage.batchPrice')"
|
|
|
+ :confirmBtnTxt="$t('device.modifyPricePage.modifySubmit')"
|
|
|
+ ref="kDialogRef"
|
|
|
+ @confirmclk="confirmClk"
|
|
|
+ >
|
|
|
+ <template #content>
|
|
|
+ <van-field
|
|
|
+ type="number"
|
|
|
+ v-model="cofficentForm.price"
|
|
|
+ :placeholder="$t('device.modifyPricePage.batchPricePlace')"
|
|
|
+ :label="$t('device.modifyPricePage.batchPrice')"
|
|
|
+ class="batch-field"
|
|
|
+ >
|
|
|
+ <template #extra>
|
|
|
+ <span class="currency-symbol">{{ currencySymbol }}</span>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ </template>
|
|
|
+ </kDialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import kDialog from "@/components/commom/kDialog/index.vue";
|
|
|
+// 导入接口
|
|
|
+import {
|
|
|
+ selectProducts,
|
|
|
+ updateProductInfo,
|
|
|
+ batchUpdatePrice,
|
|
|
+} from "@/service/device/index";
|
|
|
+import sHeader from "@/components/SimpleHeader";
|
|
|
+import { reactive, ref } from "@vue/reactivity";
|
|
|
+import { onMounted } from "@vue/runtime-core";
|
|
|
+import { useRoute } from "vue-router";
|
|
|
+import { showToast } from "vant";
|
|
|
+import { useI18n } from "vue-i18n";
|
|
|
+
|
|
|
+export default {
|
|
|
+ components: { sHeader, kDialog },
|
|
|
+ setup() {
|
|
|
+ // 引入语言
|
|
|
+ const { t } = useI18n();
|
|
|
+ // 批量修改弹窗
|
|
|
+ const kDialogRef = ref(null);
|
|
|
+ // 点击批量修改
|
|
|
+ const noticeClk = () => {
|
|
|
+ cofficentForm.price = "";
|
|
|
+ kDialogRef.value.openDialog();
|
|
|
+ };
|
|
|
+ // 修改商品信息提交参数
|
|
|
+ const params = ref();
|
|
|
+ // 点击确定按钮
|
|
|
+ const confirmClk = async() => {
|
|
|
+ if (!cofficentForm.price) {
|
|
|
+ showToast(t("device.modifyPricePage.batchPricePlace"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ params.value = {
|
|
|
+ equipmentId: cofficentForm.equipmentId,
|
|
|
+ rmbPrice: cofficentForm.price,
|
|
|
+ };
|
|
|
+ try {
|
|
|
+ const { data } = await batchUpdatePrice(params.value);
|
|
|
+ console.log(data);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ kDialogRef.value.closeDialog();
|
|
|
+ };
|
|
|
+ // 商品图片路径处理
|
|
|
+ const showSugerPhoto = (row) => {
|
|
|
+ let imgId = row.no;
|
|
|
+ if (imgId) {
|
|
|
+ return require(`../../../assets/order/spunSugar/goods/${imgId}.png`);
|
|
|
+ }
|
|
|
+ return imgId;
|
|
|
+ };
|
|
|
+ // 路由
|
|
|
+ const route = useRoute();
|
|
|
+ // 商品数据
|
|
|
+ const tableData = ref([]);
|
|
|
+ // 设备名称
|
|
|
+ const equipmentName = ref("");
|
|
|
+ // 刚进页面
|
|
|
+ onMounted(() => {
|
|
|
+ // 加载样式
|
|
|
+ const id = route.query.deviceId || "";
|
|
|
+ const name = route.query.name || "";
|
|
|
+ if (id) {
|
|
|
+ cofficentForm.equipmentId = id;
|
|
|
+ equipmentName.value = name;
|
|
|
+ getList();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 获取商品列表
|
|
|
+ const getList = () => {
|
|
|
+ selectProducts({ equipmentId: cofficentForm.equipmentId }).then((res) => {
|
|
|
+ const { data } = res.data;
|
|
|
+ if (data) {
|
|
|
+ if (data.length > 0) {
|
|
|
+ // 是否修改状态
|
|
|
+ data.forEach((item) => {
|
|
|
+ item.isEditPrice = false;
|
|
|
+ item.isEditName = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ tableData.value = data;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ // 修改的价格
|
|
|
+ const cofficentForm = reactive({
|
|
|
+ equipmentId: "",
|
|
|
+ price: "",
|
|
|
+ });
|
|
|
+ // 自定义货币符号
|
|
|
+ const currencySymbol = ref("¥");
|
|
|
+ const loginUserStr = localStorage.getItem("loginUser");
|
|
|
+ const loginUser = JSON.parse(loginUserStr);
|
|
|
+ if (loginUser.currencySymbol) {
|
|
|
+ currencySymbol.value = loginUser.currencySymbol;
|
|
|
+ } else {
|
|
|
+ currencySymbol.value = "¥";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 修改商品信息
|
|
|
+ const updateProduct = async (item, index) => {
|
|
|
+ // 排除掉isEditPrice、isEditName
|
|
|
+ if (index == 1) {
|
|
|
+ if (item.productName == "") {
|
|
|
+ showToast(t("device.enterProductName"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 修改名称
|
|
|
+ item.isEditName = false;
|
|
|
+ } else if (index == 2) {
|
|
|
+ // 修改价格
|
|
|
+ if (item.rmbPrice == "") {
|
|
|
+ showToast(t("device.enterProductPrice"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ item.codePrice = item.rmbPrice;
|
|
|
+ item.isEditPrice = false;
|
|
|
+ }
|
|
|
+ params.value = {
|
|
|
+ codePrice: item.codePrice,
|
|
|
+ equipmentId: item.equipmentId,
|
|
|
+ productName: item.productName,
|
|
|
+ name: item.name,
|
|
|
+ rmbPrice: item.rmbPrice,
|
|
|
+ sellStatus: item.sellStatus,
|
|
|
+ no: item.no,
|
|
|
+ // 故意省略 isEditPrice 和 isEditName
|
|
|
+ };
|
|
|
+ try {
|
|
|
+ const { data } = await updateProductInfo(params.value);
|
|
|
+ console.log(data);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ cofficentForm,
|
|
|
+ tableData,
|
|
|
+ showSugerPhoto,
|
|
|
+ kDialogRef,
|
|
|
+ noticeClk,
|
|
|
+ confirmClk,
|
|
|
+
|
|
|
+ // 参数
|
|
|
+
|
|
|
+ equipmentName,
|
|
|
+ currencySymbol,
|
|
|
+
|
|
|
+ // 方法
|
|
|
+ updateProduct,
|
|
|
+ };
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+@primary-color: #4d6add;
|
|
|
+@light-bg: #f5f8ff;
|
|
|
+@card-bg: #ffffff;
|
|
|
+@text-dark: #333;
|
|
|
+@text-light: #666;
|
|
|
+@text-lighter: #999;
|
|
|
+@border-color: #e4e7ec;
|
|
|
+@border-radius: 12px;
|
|
|
+@card-shadow: 0 4px 12px rgba(77, 106, 221, 0.15);
|
|
|
+@hover-shadow: 0 8px 20px rgba(77, 106, 221, 0.25);
|
|
|
+@transition: all 0.3s ease;
|
|
|
+
|
|
|
+.price-editor {
|
|
|
+ background: @light-bg;
|
|
|
+ min-height: 100vh;
|
|
|
+}
|
|
|
+
|
|
|
+.content-container {
|
|
|
+ padding: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.device-card {
|
|
|
+ background: @card-bg;
|
|
|
+ border-radius: @border-radius;
|
|
|
+ box-shadow: @card-shadow;
|
|
|
+ margin: 0 0 15px;
|
|
|
+ padding: 16px;
|
|
|
+
|
|
|
+ .device-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .header-indicator {
|
|
|
+ width: 3px;
|
|
|
+ height: 20px;
|
|
|
+ background: @primary-color;
|
|
|
+ margin-right: 12px;
|
|
|
+ border-radius: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .device-name {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #404d74;
|
|
|
+ font-weight: 550;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ max-width: 85%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.goods-card {
|
|
|
+ background: @card-bg;
|
|
|
+ border-radius: @border-radius;
|
|
|
+ box-shadow: @card-shadow;
|
|
|
+ padding: 16px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ .card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ .goods-count {
|
|
|
+ color: @text-light;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ .highlight {
|
|
|
+ color: @primary-color;
|
|
|
+ font-weight: 500;
|
|
|
+ margin: 0 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .batch-btn {
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 16px;
|
|
|
+ font-size: 13px;
|
|
|
+ border-radius: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.goods-list {
|
|
|
+ .goods-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 16px 0;
|
|
|
+ border-bottom: 1px solid @border-color;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.off-shelf {
|
|
|
+ opacity: 0.8;
|
|
|
+ background-color: fade(@text-lighter, 5%);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.goods-image-container {
|
|
|
+ width: 70px;
|
|
|
+ height: 70px;
|
|
|
+ border-radius: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+ margin-right: 15px;
|
|
|
+ flex-shrink: 0;
|
|
|
+
|
|
|
+ .goods-image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+ background-color: @light-bg;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.goods-info {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ margin-right: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.name-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .goods-name {
|
|
|
+ font-size: 15px;
|
|
|
+ color: @text-dark;
|
|
|
+ font-weight: 500;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .name-input {
|
|
|
+ width: 80%;
|
|
|
+ background: @light-bg;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 6px 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-icon {
|
|
|
+ color: @primary-color;
|
|
|
+ font-size: 18px;
|
|
|
+ padding: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .name-edit-icon {
|
|
|
+ color: @primary-color;
|
|
|
+ font-size: 18px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.price-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+
|
|
|
+ .price-input {
|
|
|
+ width: 100px;
|
|
|
+ background: @light-bg;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 6px 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-display {
|
|
|
+ color: #df5e4c;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 500;
|
|
|
+
|
|
|
+ .price {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .currency-symbol,
|
|
|
+ .currency {
|
|
|
+ color: @primary-color;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-right: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-icon {
|
|
|
+ color: @primary-color;
|
|
|
+ font-size: 18px;
|
|
|
+ padding: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.shelf-control {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 70px;
|
|
|
+
|
|
|
+ .shelf-status {
|
|
|
+ font-size: 12px;
|
|
|
+ color: @text-light;
|
|
|
+ margin-top: 6px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.batch-field {
|
|
|
+ :deep(.van-field__label) {
|
|
|
+ width: 100px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.name-edit-dialog {
|
|
|
+ :deep(.van-dialog) {
|
|
|
+ border-radius: 16px;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-content {
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .name-edit-field {
|
|
|
+ background: @light-bg;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .char-count {
|
|
|
+ text-align: right;
|
|
|
+ font-size: 12px;
|
|
|
+ color: @text-lighter;
|
|
|
+ margin-top: 8px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 480px) {
|
|
|
+ .goods-card {
|
|
|
+ padding: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .goods-item {
|
|
|
+ padding: 12px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .goods-image-container {
|
|
|
+ width: 60px;
|
|
|
+ height: 60px;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .goods-name {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price-input {
|
|
|
+ width: 90px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .shelf-control {
|
|
|
+ min-width: 60px;
|
|
|
+
|
|
|
+ .shelf-status {
|
|
|
+ font-size: 11px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.van-image__img) {
|
|
|
+ object-fit: contain !important;
|
|
|
+}
|
|
|
+</style>
|