瀏覽代碼

feat:新增页面

maliang 14 小時之前
父節點
當前提交
3421b93feb

+ 130 - 0
components/good-card/good-card.vue

@@ -0,0 +1,130 @@
+<template>
+  <view class="good-card">
+    <view @click="clickItem">
+      <view class="good-base">
+        <u-image
+          :src="goodImg"
+          width="128rpx"
+          height="128rpx"
+          class="good-img"
+        ></u-image>
+        <view class="ss-m-l-16">
+          <view class="good-base-name-box">
+            <view
+              :class="['good-base-name', { 'has-status': $slots.status }]"
+              >{{ goodName }}</view
+            >
+            <view class="good-status" v-if="$slots.status">
+              <slot name="status"></slot>
+            </view>
+          </view>
+          <view class="good-base-txm"
+            >{{ goodDesTitle }}:{{ goodDesValue }}</view
+          >
+        </view>
+      </view>
+      <gridForm
+        :columns="columns"
+        :formData="item"
+        @handleClickField="handleClickField"
+      ></gridForm>
+    </view>
+
+    <slot></slot>
+    <u-divider></u-divider>
+    <slot name="action"></slot>
+  </view>
+</template>
+
+<script>
+import gridForm from "@/components/grid-form/grid-form.vue";
+
+export default {
+  components: {
+    gridForm,
+  },
+  props: {
+    // 货物图片
+    goodImg: {
+      type: String,
+      default: "",
+    },
+    // 货物名称
+    goodName: {
+      type: String,
+      default: "",
+    },
+    goodDesTitle: {
+      type: String,
+      default: "条形码",
+    },
+    // 货物额外信息
+    goodDesValue: {
+      type: String,
+      default: "",
+    },
+    // 货物信息
+    item: {
+      type: Object,
+      default: () => {},
+    },
+    columns: {
+      type: Array,
+      default: () => [],
+    },
+  },
+  methods: {
+    handleClickField(key, formData) {
+      this.$emit("handleClickField", key, formData);
+    },
+    clickItem() {
+      this.$emit("clickItem", { ...this.item });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.good-card {
+  .good-base {
+    display: flex;
+    align-items: center;
+    padding: 0 24rpx;
+
+    &-name-box {
+      display: flex;
+    }
+    &-name {
+      width: 520rpx;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      color: #333;
+      font-family: "PingFang SC";
+      font-size: 28rpx;
+      font-weight: 500;
+      margin-bottom: 16rpx;
+
+      &.has-status {
+        width: 400rpx;
+      }
+    }
+    &-txm {
+      color: #999;
+      font-family: "PingFang SC";
+      font-size: 28rpx;
+      font-weight: 400;
+    }
+    .good-status {
+      width: 120rpx;
+      height: 44rpx;
+      border-radius: 8rpx;
+      font-family: "PingFang SC";
+      font-weight: 400;
+      font-size: 22rpx;
+      line-height: 44rpx;
+      text-align: center;
+    }
+  }
+}
+</style>

+ 82 - 0
components/grid-form/grid-form.vue

@@ -0,0 +1,82 @@
+<template>
+  <view class="grid-from">
+    <view
+      class="grid-from-item"
+      v-for="(col, index) in _columns"
+      :key="index"
+      @click.stop="handleClickField(col.key)"
+    >
+      <view class="grid-from-item-label">{{ col.title }}</view>
+      <view class="grid-from-item-value">{{ getFieldValue(col) }}</view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    /**
+     * title: 标题
+     * key: key值
+     * formatter: 格式化函数
+     * isShow: 显/隐函数
+     */
+    columns: {
+      type: Array,
+      default: () => [],
+    },
+    formData: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  computed: {
+    _columns() {
+      return this.columns.filter((col) => {
+        if (col.isShow && col.isShow instanceof Function) {
+          return col.isShow(col.key, { ...this.formData }, col);
+        }
+        return true;
+      });
+    },
+  },
+  methods: {
+    /**
+     * 点击事件
+     * @param {String} key 字段名
+     */
+    handleClickField(key) {
+      this.$emit("handleClickField", key, { ...this.formData });
+    },
+    getFieldValue(col) {
+      const formData = { ...this.formData };
+      if (col.formatter && col.formatter instanceof Function) {
+        return col.formatter(col.key, formData, col);
+      }
+      return formData[col.key] || "-";
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.grid-from {
+  display: grid;
+  grid-template-columns: 33% 33% 33%;
+  padding: 0 24rpx;
+  &-item {
+    font-family: "PingFang SC";
+    font-weight: 400;
+    margin-top: 24rpx;
+    &-label {
+      color: #999;
+      font-size: 24rpx;
+      margin-bottom: 16rpx;
+    }
+    &-value {
+      color: #000;
+      font-size: 28rpx;
+    }
+  }
+}
+</style>

+ 29 - 0
pages.json

@@ -107,6 +107,35 @@
           "bounce": "none"
         }
       }
+    },
+    {
+      "path": "pages/goods-enter/index",
+      "style": {
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": true,
+        "onReachBottomDistance": 50,
+        "app-plus": {
+          "bounce": "none"
+        }
+      }
+    },
+    {
+      "path": "pages/goods-enter/addGood",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/audit-task/index",
+      "style": {
+        "navigationBarTitleText": ""
+      }
+    },
+    {
+      "path": "pages/audit-task/go-audit",
+      "style": {
+        "navigationBarTitleText": ""
+      }
     }
   ],
   /* 分包预载配置 */

+ 139 - 0
pages/audit-task/components/reject-pop.vue

@@ -0,0 +1,139 @@
+<template>
+  <u-popup
+    :show="show"
+    mode="center"
+    @close="close"
+    @open="open"
+    :round="10"
+    :closeOnClickOverlay="false"
+    :safeAreaInsetBottom="false"
+    width="580rpx"
+  >
+    <view class="location-edit-popup">
+      <view class="popup-header">
+        <text class="popup-title">驳回复核任务</text>
+        <u-icon name="close" size="20" @click="close"></u-icon>
+      </view>
+
+      <u-form
+        :model="formData"
+        labelPosition="top"
+        labelWidth="100%"
+        :borderBottom="false"
+      >
+        <u-form-item label="请输入驳回原因" prop="reason" :borderBottom="false">
+          <u--textarea
+            v-model="formData.reason"
+            placeholder="请输入"
+            :maxlength="100"
+            count
+          ></u--textarea>
+        </u-form-item>
+      </u-form>
+
+      <view class="btn-group">
+        <u-button
+          class="btn cancel-btn"
+          :plain="true"
+          shape="square"
+          @click="onCancel"
+          >取消</u-button
+        >
+        <u-button
+          class="btn confirm-btn"
+          type="primary"
+          shape="square"
+          @click="onConfirm"
+          >确认</u-button
+        >
+      </view>
+    </view>
+  </u-popup>
+</template>
+
+<script>
+export default {
+  name: "RejectPopup",
+  props: {
+    show: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      formData: {
+        reason: "",
+      },
+      rules: {
+        reason: {
+          type: "string",
+          required: true,
+          message: "请输入驳回原因",
+          trigger: ["blur", "change"],
+        },
+      },
+    };
+  },
+  watch: {},
+  methods: {
+    close() {
+      this.$emit("update:show", false);
+    },
+    onCancel() {
+      this.close();
+      this.$emit("cancel");
+    },
+    onConfirm() {},
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.location-edit-popup {
+  padding: 30rpx;
+  width: 580rpx;
+
+  .popup-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 30rpx;
+
+    .popup-title {
+      font-size: 36rpx;
+      font-weight: 500;
+      color: #333333;
+    }
+  }
+
+  .mt-20 {
+    margin-top: 20rpx;
+  }
+
+  .btn-group {
+    display: flex;
+    justify-content: space-between;
+    margin-top: 40rpx;
+
+    .btn {
+      flex: 1;
+      height: 88rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 32rpx;
+
+      &.cancel-btn {
+        margin-right: 20rpx;
+        color: #666666;
+        border-color: #dddddd;
+      }
+
+      &.confirm-btn {
+        background-color: #2979ff;
+      }
+    }
+  }
+}
+</style>

+ 189 - 0
pages/audit-task/components/task-item.vue

@@ -0,0 +1,189 @@
+<template>
+  <view class="task-item">
+    <view @click="detailClick">
+      <view class="task-head">
+        <view class="sn-box">单据编号:{{ item.number }}</view>
+        <view>
+          <view class="tips tips-red" v-if="item.status == 1">待审核</view>
+          <view class="tips tips-greed" v-if="item.status == 2">已入库</view>
+          <view class="tips tips-yellow" v-if="item.status == 4">入库中</view>
+        </view>
+      </view>
+      <view class="task-line">
+        <view>客户名称:</view>
+        <view>{{ item.supplierName }}</view>
+      </view>
+      <view class="task-line">
+        <view>单据日期:</view>
+        <view>{{ item.createTime }}</view>
+      </view>
+      <view class="task-line">
+        <view class="task-line2">
+          <view>类别:</view>
+          <view>采购入库</view>
+        </view>
+        <view class="task-line2">
+          <view>入库人:</view>
+          <view>张三</view>
+        </view>
+        <!-- <view class="task-line2">
+          <view>出库人:</view>
+          <view class="task-num">{{ item.goodsTypeCount || 0 }}种</view>
+        </view> -->
+      </view>
+      <view class="task-line">
+        <view class="task-line2">
+          <view>货物总数:</view>
+          <view class="task-num">{{ item.goodsQuantity }}件</view>
+        </view>
+        <view class="task-line2">
+          <view>货物种类:</view>
+          <view class="task-num">{{ item.goodsTypeCount || 0 }}种</view>
+        </view>
+      </view>
+    </view>
+    <view class="action-box">
+      <view class="task-line" style="font-size: 24rpx; margin: 0">
+        <view>入库时间:</view>
+        <view>2021-11-21 00:00:03</view>
+      </view>
+      <view class="task-bottom">
+        <view
+          class="btn btn-1"
+          v-if="item.status == 1 || item.status == 4"
+          @click="toAudit"
+          >去审核</view
+        >
+        <view class="btn btn-2" v-else @click="toDetail">详情</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    item: {
+      type: Object,
+      default: () => {},
+    },
+    type: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {};
+  },
+  methods: {
+    toAudit() {
+      this.$emit("toAudit", this.item);
+    },
+    toDetail() {
+      this.$emit("toDetail", this.item);
+    },
+    detailClick() {
+      if (this.item.status == 1 || this.item.status == 4) {
+        this.toAudit();
+      } else {
+        this.toDetail();
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.task-item {
+  width: 100%;
+  background-color: #fff;
+  border-radius: 16rpx;
+  padding: 24rpx 24rpx 0;
+  margin-bottom: 24rpx;
+  .task-head {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .sn-box {
+      color: #333;
+      font-family: "PingFang SC";
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+    .tips {
+      font-family: "PingFang SC";
+      font-size: 22rpx;
+      font-weight: 400;
+      width: 120rpx;
+      height: 44rpx;
+      border-radius: 8rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .tips-red {
+      color: #ff3b1d;
+      background: rgba(255, 59, 29, 0.2);
+    }
+    .tips-greed {
+      color: #00b97b;
+      background: rgba(0, 185, 123, 0.2);
+    }
+    .tips-yellow {
+      color: #f57701;
+      background: rgba(245, 151, 1, 0.2);
+    }
+  }
+
+  .task-line {
+    display: flex;
+    align-items: center;
+    color: #666;
+    font-family: "PingFang SC";
+    font-size: 28rpx;
+    font-weight: 400;
+    margin-top: 16rpx;
+  }
+  .task-line2 {
+    width: 50%;
+    display: flex;
+    align-items: center;
+    .task-num {
+      color: #0256ff;
+    }
+  }
+
+  .action-box {
+    margin-top: 32rpx;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+  .task-bottom {
+    border-top: 1px solid #f0f0f0;
+    height: 104rpx;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    .btn {
+      width: 144rpx;
+      height: 56rpx;
+      border-radius: 8rpx;
+      font-size: 28rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-family: "PingFang SC";
+    }
+    .btn-1 {
+      background: #0256ff;
+      color: #fff;
+    }
+    .btn-2 {
+      border: 1px solid #0256ff;
+      background: rgba(2, 86, 255, 0.2);
+      color: #0256ff;
+    }
+  }
+}
+</style>

+ 411 - 0
pages/audit-task/go-audit.vue

@@ -0,0 +1,411 @@
+<template>
+  <view class="deliver-page">
+    <u-navbar
+      height="40px"
+      title="复核任务详情"
+      bgColor="#0256FF"
+      :titleStyle="{ color: '#fff' }"
+      leftIconColor="#fff"
+      autoBack
+      placeholder
+    >
+    </u-navbar>
+    <view class="container_main">
+      <view class="info-box" :class="isUnfold ? '' : 'min-height'">
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>入库单号</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.number }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>收入仓库</text>
+          </view>
+          <view class="info-line-value">
+            {{ depotInfo ? depotInfo.depotName : "" }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>供应商</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.supplierName }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>入库数量</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.goodsQuantity }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>入库种类</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.goodsTypeCount }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>制单日期</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.createTime }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>制单人</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.createName || "-" }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>入库类型</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.subType }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>入库人</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.operName || "-" }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>备注信息</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.remark || "-" }}
+          </view>
+        </view>
+        <view class="info-line">
+          <view class="info-line-label">
+            <text>入库时间</text>
+          </view>
+          <view class="info-line-value">
+            {{ orderInfo.operTime }}
+          </view>
+        </view>
+      </view>
+      <view class="btn-box">
+        <view class="btn-cont" @click="isUnfold = !isUnfold">
+          <text>{{ isUnfold ? "收起" : "展开" }}</text>
+          <u-icon :name="isUnfold ? 'arrow-up' : 'arrow-down'"></u-icon>
+        </view>
+      </view>
+
+      <!-- 货物清单 -->
+      <view class="cargo-list">
+        <view class="cargo-list-title">
+          <view>入库货物清单</view>
+          <view class="cargo-list-title-tips">(轻触货物查看详情)</view>
+        </view>
+        <block v-for="(item, i) in goodsList" :key="i">
+          <good-item
+            :item="item"
+            @toDetail="toDetail"
+            :show-print="true"
+            @print="(e) => handlePrint(e.id, '1', status)"
+          >
+            <view class="num-box">
+              <view class="num-box-text">已确认入库数量</view>
+              <u-number-box
+                v-model="item.actualQuantityInStorage"
+                disabled
+                :inputWidth="56"
+              >
+              </u-number-box>
+            </view>
+          </good-item>
+        </block>
+      </view>
+    </view>
+    <view class="footer-box">
+      <u-button class="cancelBtn" @tap="showReject = true">驳回</u-button>
+      <u-button class="submitBtn">复核通过</u-button>
+    </view>
+    <!-- 打印条码弹框 -->
+    <print-pop
+      :show.sync="blePrintPop.show"
+      :info="blePrintPop.data"
+      @confirm="startPrint"
+    ></print-pop>
+    <!-- 选择蓝牙设备弹框 -->
+    <ble-pop
+      :show.sync="bleSelectPop.show"
+      :list="discoveredDevices"
+      @close="closeBleSelectPop"
+      @refresh="refreshBleDevice"
+      @selectItem="handleSelectBle"
+    ></ble-pop>
+
+    <ble-tip-pop
+      v-model="bleErrorTipPop.show"
+      :is-center="true"
+      @confirm="bleErrorTipConfirm"
+      :content="bleErrorTipPop.content"
+      :extraText="bleErrorTipPop.extraText"
+    >
+    </ble-tip-pop>
+    <rejectPop :show.sync="showReject" />
+  </view>
+</template>
+
+<script>
+import goodItem from "@/components/good-item/good-item.vue";
+import { orderDetail, orderInfo } from "@/common/request/apis/purchase";
+import { mapGetters } from "vuex";
+import blePrintMixin from "@/common/mixins/blePrintMixin.js";
+import rejectPop from "./components/reject-pop.vue";
+export default {
+  mixins: [blePrintMixin],
+  components: {
+    goodItem,
+    rejectPop,
+  },
+  data() {
+    return {
+      errorShow: false,
+      successShow: false,
+      value: 0,
+      isUnfold: true, //是否展开
+      orderInfo: {},
+      goodsList: [],
+      status: null,
+
+      showReject: false,
+    };
+  },
+  onLoad(e) {
+    this.status = e.status;
+    this.getOrderInfo(e.id);
+    this.getOrderDetail(e.id);
+  },
+  computed: {
+    ...mapGetters(["depotInfo"]),
+  },
+  methods: {
+    getOrderInfo(id) {
+      orderInfo(id).then((res) => {
+        if (res.code == 200) {
+          this.orderInfo = res.data;
+        }
+      });
+    },
+    getOrderDetail(id) {
+      orderDetail(id).then((res) => {
+        if (res.code == 200) {
+          res.data.rows.forEach((item) => {
+            if (item.imgName && item.imgName.length > 0) {
+              item.imgNameArr = item.imgName.split(",");
+            } else {
+              item.imgNameArr = [];
+            }
+          });
+          this.goodsList = res.data.rows;
+          console.log("this.goodsList==========", this.goodsList);
+        }
+      });
+    },
+    submitClick() {},
+    confirm() {
+      this.errorShow = false;
+    },
+    backClick() {},
+    // 扫码确认
+    scanConfirm() {},
+    manualClick() {
+      this.goodsShow = true;
+    },
+    toDetail(val) {
+      uni.navigateTo({
+        url: `/pages/goods/detail?id=${val.id}&name=${val.materialName}&materialId=${val.materialId}`,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.deliver-page {
+  min-height: 100vh;
+  background-color: #f0f6fb;
+  padding-bottom: 130rpx;
+
+  .container_main {
+    padding: 24rpx;
+
+    .info-box {
+      background-color: #fff;
+      border-radius: 16rpx 16rpx 0 0;
+      padding: 24rpx 24rpx 0 24rpx;
+
+      .info-line {
+        border-bottom: 1px solid #f4f4f4;
+        min-height: 92rpx;
+        color: #333;
+        font-family: "PingFang SC";
+        font-size: 28rpx;
+        font-weight: 400;
+        display: flex;
+        align-items: center;
+
+        &-label {
+          width: 162rpx;
+        }
+
+        .must-box {
+          color: #ff3b1d;
+        }
+      }
+    }
+
+    .min-height {
+      height: 300rpx;
+      overflow: hidden;
+    }
+
+    .btn-box {
+      height: 112rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background-color: #fff;
+      border-radius: 0 0 16rpx 16rpx;
+
+      .btn-cont {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 154rpx;
+        height: 56rpx;
+        border-radius: 120rpx;
+        border: 1px solid #d9d9d9;
+        color: #666;
+        font-family: "PingFang SC";
+        font-size: 28rpx;
+        font-weight: 400;
+      }
+    }
+
+    .cargo-list {
+      padding: 24rpx 0;
+      background-color: #fff;
+      margin-top: 24rpx;
+      border-radius: 16rpx;
+
+      .cargo-list-title {
+        font-family: "PingFang SC";
+        font-size: 32rpx;
+        font-style: normal;
+        font-weight: bold;
+        display: flex;
+        align-items: center;
+        position: relative;
+        padding-left: 50rpx;
+
+        &::after {
+          content: "";
+          display: block;
+          width: 6rpx;
+          height: 30rpx;
+          border-radius: 100px;
+          background: #0256ff;
+          position: absolute;
+          top: 50%;
+          left: 24rpx;
+          transform: translateY(-50%);
+        }
+
+        .cargo-list-title-tips {
+          color: #0256ff;
+          font-size: 24rpx;
+          font-weight: 400;
+        }
+      }
+
+      .num-box {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 0 48rpx 0 26rpx;
+        .num-box-text {
+          color: #666;
+          font-family: "PingFang SC";
+          font-size: 28rpx;
+          font-weight: 400;
+        }
+        .input {
+          width: 112rpx;
+          text-align: center;
+          border-bottom: 1px solid #dadada;
+          margin: 0 8rpx;
+        }
+        .minus {
+          width: 40rpx;
+          height: 40rpx;
+          border-radius: 8rpx;
+          border: 1px solid #dadada;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+        }
+        .plus {
+          width: 40rpx;
+          height: 40rpx;
+          border-radius: 8rpx;
+          background-color: #dadada;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+        }
+      }
+    }
+  }
+
+  .footer-box {
+    background-color: #fff;
+    height: 176rpx;
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .cancelBtn {
+      width: 244rpx;
+      height: 80rpx;
+      border-radius: 16rpx;
+      color: #666;
+      font-family: "PingFang SC";
+      font-size: 32rpx;
+      font-weight: 500;
+      margin-right: 20rpx;
+    }
+    .submitBtn {
+      width: 244rpx;
+      height: 80rpx;
+      border-radius: 16rpx;
+      background: #0256ff;
+      color: #fff;
+      font-size: 32rpx;
+      font-weight: 500;
+    }
+  }
+}
+</style>

+ 354 - 0
pages/audit-task/index.vue

@@ -0,0 +1,354 @@
+<template>
+  <view class="picking-task-page">
+    <u-navbar
+      height="40px"
+      title="复核任务"
+      bgColor="#F0F6FB"
+      autoBack
+      placeholder
+    >
+      <view class="u-nav-slot depot-label" slot="right">
+        <view class="name">{{ curDepotName }}</view>
+      </view>
+    </u-navbar>
+    <view class="container_main">
+      <u-sticky :offsetTop="offsetTop" bgColor="#F0F6FB">
+        <view class="search-box">
+          <u-search
+            placeholder="请输入单据编号"
+            bgColor="#fff"
+            shape="square"
+            v-model="params.number"
+            :showAction="false"
+            @search="searchClick"
+            @clear="searchClick"
+          ></u-search>
+          <view class="flex_box" @click="scanCode">
+            <view class="scan-text">扫描单据二维码</view>
+            <view class="scan-icon">
+              <image src="@/static/image/scan-icon.png" mode=""></image>
+            </view>
+          </view>
+        </view>
+        <view class="type-box flex_box">
+          <view class="type-item" @click="tabClick(1)">
+            <view class="type-val">{{ type1 }}</view>
+            <u-icon name="arrow-down-fill" color="#999999" size="12"></u-icon>
+          </view>
+          <view class="type-item" @click="tabClick(2)">
+            <view class="type-val">{{ type2 }}</view>
+            <u-icon name="arrow-down-fill" color="#999999" size="12"></u-icon>
+          </view>
+        </view>
+      </u-sticky>
+      <view class="task-cont">
+        <block v-for="(item, i) in taskList" :key="`${item.id}-${item.status}`">
+          <task-item
+            :item="item"
+            @toAudit="toAudit"
+            @toDetail="toDetail"
+            type="caigou"
+          ></task-item>
+        </block>
+        <u-loadmore v-if="taskList.length > 0" :status="status" />
+        <u-empty
+          mode="data"
+          text="暂无内容"
+          marginTop="60"
+          icon="https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com/APP/no-notifcations.png"
+          v-if="taskList.length == 0"
+        ></u-empty>
+      </view>
+    </view>
+    <!-- 状态 -->
+    <u-picker
+      :show="statusShow"
+      keyName="label"
+      :defaultIndex="defaultIndex2"
+      :columns="statusColumns"
+      @confirm="statusConfirm"
+      @cancel="statusShow = false"
+    ></u-picker>
+    <!-- 月份 -->
+    <u-picker
+      :show="dateShow"
+      :defaultIndex="defaultIndex3"
+      :columns="dateColumns"
+      @confirm="dateConfirm"
+      @cancel="dateShow = false"
+    ></u-picker>
+  </view>
+</template>
+
+<script>
+import taskItem from "./components/task-item.vue";
+import {
+  purchaseInventory,
+  orderStartHandle,
+} from "@/common/request/apis/purchase";
+import { mapGetters } from "vuex";
+
+export default {
+  components: {
+    taskItem,
+  },
+  data() {
+    return {
+      offsetTop: 0,
+      type1: "全部",
+      type2: "月份",
+      statusShow: false,
+      dateShow: false,
+      statusColumns: [
+        [
+          {
+            label: "全部",
+            id: "",
+          },
+          {
+            label: "待入库",
+            id: "1",
+          },
+          {
+            label: "入库中",
+            id: "4",
+          },
+          {
+            label: "已入库",
+            id: "2",
+          },
+        ],
+      ],
+      dateColumns: [
+        [
+          "全年",
+          "一月",
+          "二月",
+          "三月",
+          "四月",
+          "五月",
+          "六月",
+          "七月",
+          "八月",
+          "九月",
+          "十月",
+          "十一月",
+          "十二月",
+        ],
+      ],
+      defaultIndex2: [],
+      defaultIndex3: [],
+      taskList: [
+        {
+          number: "CGDD00000000692",
+          status: "1",
+          id: "1",
+          supplierName: "快马阳光便利店",
+          createTime: "2021-11-21 00:00:03",
+          goodsQuantity: "55",
+          goodsTypeCount: "5",
+        },
+      ],
+      params: {
+        beginTime: "",
+        endTime: "",
+        number: "",
+        status: "",
+        currentPage: 1,
+        pageSize: 10,
+      },
+      status: "loadmore",
+      lastPage: 1,
+    };
+  },
+  computed: {
+    ...mapGetters(["depotInfo"]),
+    curDepotId() {
+      return this.depotInfo ? this.depotInfo.id : "";
+    },
+    curDepotName() {
+      return this.depotInfo ? this.depotInfo.depotName : "";
+    },
+  },
+  onLoad() {
+    let systemInfo = uni.getSystemInfoSync();
+    let statusBarHeight = systemInfo.statusBarHeight;
+    this.offsetTop = statusBarHeight + 40;
+    // this.init();
+  },
+  onShow() {
+    uni.$on("scanFinish", (data) => {
+      this.params.number = data;
+      this.init();
+    });
+    if (uni.getStorageSync("orderRefresh")) {
+      this.init();
+      uni.removeStorageSync("orderRefresh");
+    }
+  },
+  onHide() {
+    uni.$off("scanFinish");
+  },
+  onUnload() {
+    uni.$off("scanFinish");
+  },
+  onReachBottom() {
+    if (this.params.currentPage < this.lastPage) {
+      this.params.currentPage++;
+      this.getPurchaseInventory();
+    }
+  },
+  methods: {
+    scanCode() {
+      this.$scan.scanCode();
+    },
+    init() {
+      uni.showLoading();
+      this.params.currentPage = 1;
+      this.taskList = [];
+      this.getPurchaseInventory();
+    },
+    searchClick() {
+      this.init();
+    },
+    // 点击操作
+    toOrderStartHandle(id, status) {
+      orderStartHandle(id).then((res) => {
+        if (res.code == 200) {
+          uni.navigateTo({
+            url: `/pages/purchase/put-storage?id=${id}&status=${status}`,
+          });
+        }
+      });
+    },
+    tabClick(type) {
+      switch (type) {
+        case 1:
+          this.statusShow = true;
+          break;
+        case 2:
+          this.dateShow = true;
+          break;
+        default:
+          break;
+      }
+    },
+    getPurchaseInventory() {
+      console.log("getPurchaseInventory======", this.params);
+      purchaseInventory({ ...this.params, depotId: this.curDepotId })
+        .then((res) => {
+          if (res.code == 200) {
+            this.status = "loading";
+            this.lastPage = Math.ceil(
+              (res.data.total * 1) / this.params.pageSize
+            );
+            if (this.params.currentPage < this.lastPage) {
+              this.status = "loadmore";
+            } else {
+              this.status = "nomore";
+            }
+            this.taskList = [...this.taskList, ...res.data.rows];
+            console.log("this.taskList=======", this.taskList);
+          }
+          uni.hideLoading();
+        })
+        .catch((err) => {
+          uni.hideLoading();
+        });
+    },
+    statusConfirm(val) {
+      this.type1 = val.value[0].label;
+      this.params.status = val.value[0].id;
+      this.statusShow = false;
+      this.init();
+    },
+    dateConfirm(val) {
+      this.type2 = val.value[0];
+      this.dateShow = false;
+      let month = val.indexs[0];
+      this.getLastDayOfMonth(month);
+      this.init();
+    },
+    // 获取开始时间、结束时间
+    getLastDayOfMonth(month) {
+      let year = new Date().getFullYear();
+      if (month != 0) {
+        let monthStart = new Date(year, month, 0).getDate();
+        this.params.beginTime = `${year}-${month}-01`;
+        this.params.endTime = `${year}-${month}-${monthStart}`;
+      } else {
+        this.params.beginTime = "";
+        this.params.endTime = "";
+      }
+    },
+    // 审核
+    toAudit(val) {
+      uni.navigateTo({
+        url: `/pages/audit-task/go-audit?id=${val.id}&status=${val.status}`,
+      });
+      // this.toOrderStartHandle(val.id, val.status);
+    },
+    toDetail(val) {
+      uni.navigateTo({
+        url: `/pages/purchase/detail?id=${val.id}&status=${val.status}`,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.picking-task-page {
+  min-height: 100vh;
+  background: #f0f6fb;
+  .container_main {
+    .search-box {
+      display: flex;
+      align-items: center;
+      padding: 0 32rpx;
+      .scan-text {
+        color: #333;
+        font-family: "PingFang SC";
+        font-size: 24rpx;
+        font-weight: 400;
+        margin-right: 20rpx;
+        margin-left: 30rpx;
+      }
+      .scan-icon {
+        width: 36rpx;
+        height: 36rpx;
+        background-color: #fff;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        image {
+          width: 24rpx;
+          height: 24rpx;
+        }
+      }
+    }
+
+    .type-box {
+      .type-item {
+        width: 50%;
+        height: 88rpx;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        .type-val {
+          color: #000;
+          font-family: "PingFang SC";
+          font-size: 28rpx;
+          font-weight: 400;
+          margin-right: 10rpx;
+        }
+      }
+    }
+
+    .task-cont {
+      padding: 0 24rpx;
+    }
+  }
+}
+</style>

+ 226 - 3
pages/goods-enter/addGood.vue

@@ -1,7 +1,230 @@
-<template></template>
+<template>
+  <view class="goods-page">
+    <u-navbar
+      height="40px"
+      title="新增录入"
+      bgColor="rgba(2, 86, 255, 1)"
+      autoBack
+      placeholder
+      titleStyle="color:#fff"
+      leftIconColor="#fff"
+    >
+      <view class="u-nav-slot depot-label" slot="right">
+        <view class="name" style="color: #fff">{{ curDepotName }}</view>
+      </view>
+    </u-navbar>
+    <view class="container_main">
+      <u--form
+        labelPosition="left"
+        :model="form"
+        :rules="rules"
+        labelWidth="90"
+      >
+        <u-form-item
+          label="货物条码"
+          prop="barCode"
+          borderBottom
+          customStyle="padding: 30rpx 0"
+        >
+          <u-input v-model="form.barCode" border="none" placeholder="请输入">
+            <u-image
+              slot="suffix"
+              src="@/static/image/scan-icon-2.png"
+              width="40rpx"
+              height="40rpx"
+              @click="scanCode"
+            ></u-image>
+          </u-input>
+        </u-form-item>
+        <u-form-item
+          label="货物名称"
+          prop="materialName"
+          borderBottom
+          customStyle="padding: 30rpx 0"
+        >
+          <u-input
+            v-model="form.materialName"
+            border="none"
+            placeholder="请输入"
+          ></u-input>
+        </u-form-item>
+        <u-form-item
+          label="规格"
+          prop="materialStandard"
+          borderBottom
+          customStyle="padding: 30rpx 0"
+        >
+          <u-input
+            v-model="form.materialStandard"
+            border="none"
+            placeholder="请输入"
+          ></u-input>
+        </u-form-item>
+        <u-form-item
+          label="生产日期"
+          prop="productionDate"
+          borderBottom
+          customStyle="padding: 30rpx 0"
+        >
+          <view
+            :class="['date-val', { grey: !form.productionDate }]"
+            @click="showDatePicker = true"
+            >{{ form.productionDate ? form.productionDate : "请输入" }}</view
+          >
+        </u-form-item>
+        <u-form-item
+          label="上传图片"
+          prop="img"
+          borderBottom
+          customStyle="padding: 30rpx 0"
+        >
+          <u-upload
+            :fileList="fileList"
+            @afterRead="afterRead"
+            @delete="deletePic"
+            name="file"
+            width="120rpx"
+            height="120rpx"
+            :maxCount="2"
+          >
+            <u-image
+              src="@/static/image/upload-img.png"
+              width="120rpx"
+              height="120rpx"
+            ></u-image>
+          </u-upload>
+        </u-form-item>
+        <u-form-item
+          label="库位"
+          prop="position"
+          borderBottom
+          customStyle="padding: 30rpx 0"
+        >
+          <u-input
+            v-model="form.position"
+            border="none"
+            placeholder="请输入"
+          ></u-input>
+        </u-form-item>
+      </u--form>
+    </view>
+    <u-datetime-picker
+      :show="showDatePicker"
+      @cancel="showDatePicker = false"
+      @confirm="confirmDate"
+      v-model="dateVal"
+      mode="date"
+    ></u-datetime-picker>
+    <!-- 新增录入-->
+    <view class="footer">
+      <u-button class="add-btn" type="primary" plain @click="save">
+        保存
+      </u-button>
+    </view>
+  </view>
+</template>
 
 <script>
-export default {};
+import { mapGetters } from "vuex";
+
+export default {
+  data() {
+    return {
+      form: {
+        materialName: "",
+        barCode: "",
+        productionDate: "",
+        unit: "",
+      },
+      rules: {},
+      showDatePicker: false,
+      dateVal: "",
+      fileList: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["depotInfo"]),
+    curDepotId() {
+      return this.depotInfo ? this.depotInfo.id : "";
+    },
+    curDepotName() {
+      return this.depotInfo ? this.depotInfo.depotName : "";
+    },
+  },
+  onHide() {
+    uni.$off("scanFinish");
+  },
+  onShow() {
+    uni.$on("scanFinish", (data) => {
+      this.form.barCode = data;
+    });
+  },
+  methods: {
+    scanCode() {
+      this.$scan.scanCode();
+    },
+    confirmDate(e) {
+      console.log("confirmDate====", e);
+      const { value } = e;
+      this.form.productionDate = this.$u.date(value, "yyyy-mm-dd");
+      console.log("form====", this.form);
+      this.showDatePicker = false;
+    },
+    deletePic(e) {
+      console.log("deletePic====", e);
+      this.fileList.splice(e.index, 1);
+    },
+    afterRead(e) {
+      console.log("afterRead====", e);
+      const { file } = e;
+      this.fileList.push(file);
+    },
+    save() {},
+  },
+};
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.goods-page {
+  min-height: 100vh;
+  background-color: #f0f6fb;
+  .container_main {
+    margin: 24rpx;
+    background-color: #fff;
+    border-radius: 16rpx;
+    padding: 24rpx;
+  }
+}
+
+.footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 144rpx;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  .add-btn {
+    width: 700rpx;
+    height: 88rpx;
+    border-radius: 16rpx;
+    font-size: 36rpx;
+    font-weight: bold;
+    color: #fff;
+    background-color: #0256ff;
+    line-height: 88rpx;
+    text-align: center;
+  }
+}
+
+.date-val {
+  width: 100%;
+  font-size: 28rpx;
+}
+.grey {
+  color: #999;
+}
+</style>

+ 197 - 38
pages/goods-enter/index.vue

@@ -7,26 +7,53 @@
       autoBack
       placeholder
     >
-      <view class="u-nav-slot depot-label" slot="right" @click="stashClick">
+      <view class="u-nav-slot depot-label" slot="right">
         <view class="name">{{ curDepotName }}</view>
       </view>
     </u-navbar>
     <view class="container_main">
       <u-sticky :offsetTop="offsetTop" bgColor="#fff">
-        <view class="search-box">
-          <u-search
-            placeholder="请输入单据编号或名称"
-            shape="square"
-            v-model="query.number"
-            :showAction="false"
-            :clearabled="true"
-            @search="handleSearch"
-            @clear="handleSearch"
-          ></u-search>
+        <view class="head-box">
+          <view class="search-box">
+            <u-search
+              placeholder="输入关键字进行货物的模糊查询"
+              shape="square"
+              :showAction="false"
+              @search="handleSearch"
+              @clear="handleSearch"
+              v-model="query.number"
+            ></u-search>
+            <view class="scan-icon flex_box flex_row_center" @click="">
+              <image src="@/static/image/scan-icon-2.png" mode=""></image>
+            </view>
+          </view>
         </view>
       </u-sticky>
       <view class="content-box">
-        <view class="content-box-val"> </view>
+        <view class="content-list" v-if="list.length > 0">
+          <view class="content-list-title">
+            <view>入库货物清单</view>
+            <view class="content-list-title-tips">(轻触货物查看详情)</view>
+          </view>
+          <goodCard
+            v-for="(item, i) in list"
+            :key="i"
+            :goodImg="item.imgNameArr[0] || ''"
+            :goodName="item.materialName"
+            :goodDesValue="item.barCode"
+            goodDesTitle="条形码"
+            :columns="columns"
+            :item="item"
+            @handleClickField="handleClickField"
+            @clickItem="handleClickItem"
+          >
+            <view slot="status">
+              <view class="dsh">待审核</view>
+              <!-- <view class="zc">正常</view>
+              <view class="ybh">已驳回</view> -->
+            </view>
+          </goodCard>
+        </view>
         <u-empty
           mode="data"
           text="暂无内容"
@@ -41,35 +68,24 @@
           @loadmore="onLoadMore"
         />
       </view>
+      <!-- 新增录入-->
+      <view class="footer">
+        <u-button class="add-btn" type="primary" plain @click="goAddGood">
+          新增录入
+        </u-button>
+      </view>
     </view>
-
-    <error-pop
-      v-model="actionPop.errorShow"
-      isCenter
-      cancelBtnText="取消"
-      confirmBtnText="确定"
-      @close="actionPop.errorShow = false"
-      @confirm="submit"
-      :content="actionPop.errorText"
-    ></error-pop>
   </view>
 </template>
 
 <script>
-import checkItem from "./components/check-item.vue";
-
-import {
-  taskStocktakingList,
-  startTask,
-  taskComplete,
-  taskStocktakingDetail,
-} from "@/common/request/apis/inventoryTask";
+import { taskStocktakingList } from "@/common/request/apis/inventoryTask";
 import { mapGetters } from "vuex";
+import goodCard from "@/components/good-card/good-card.vue";
 
 export default {
   components: {
-    checkItem,
-    errorPop,
+    goodCard,
   },
   data() {
     return {
@@ -80,10 +96,59 @@ export default {
       currentPage: 1,
       pageSize: 10,
       loadStatus: "loadmore", //加载前值为loadmore,加载中为loading,没有数据为nomore
-      list: [],
 
-      // 中心仓
-      cangName: "",
+      columns: [
+        { title: "规格", key: "materialStandard" },
+        { title: "批次号", key: "patchNumber" },
+        { title: "生产日期", key: "productionDate" },
+        { title: "库位", key: "position" },
+        {
+          title: "库存",
+          key: "inventory",
+          formatter: (key, formData) => {
+            const inventory = formData.inventory
+              ? (formData.inventory * 1).toFixed(0)
+              : "0";
+            return `${inventory}${formData.commodityUnit || ""}`;
+          },
+        },
+        { title: "录入时间", key: "lrDate" },
+      ],
+      list: [
+        {
+          id: 1,
+          materialName:
+            "货物名称1货物名称1货物名称1货物名称1货物名称1货物名称1",
+          imgNameArr: [
+            "https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com/APP/no-notifcations.png",
+          ],
+          barCode: "6904045405",
+          materialStandard: "500ml",
+          productionDate: "2024-10-01",
+          lrDate: "2024-10-01",
+          inventory: 10,
+          commodityUnit: "瓶",
+          position: "A-1-1",
+          status: 1,
+          patchNumber: "12345678966",
+        },
+        {
+          id: 2,
+          materialName: "货物名称2",
+          imgNameArr: [
+            "https://xiangli-erp.oss-cn-hangzhou.aliyuncs.com/APP/no-notifcations.png",
+          ],
+          barCode: "6904045405",
+          materialStandard: "500ml",
+          productionDate: "2024-10-01",
+          lrDate: "2024-10-02",
+          inventory: 10,
+          commodityUnit: "瓶",
+          position: "A-1-2",
+          status: 1,
+          patchNumber: "12345678966",
+        },
+      ],
     };
   },
   computed: {
@@ -99,7 +164,7 @@ export default {
     let systemInfo = uni.getSystemInfoSync();
     let statusBarHeight = systemInfo.statusBarHeight;
     this.offsetTop = statusBarHeight + 40;
-    this.loadData();
+    // this.loadData();
   },
   onShow() {},
   onPullDownRefresh() {
@@ -158,6 +223,18 @@ export default {
     handleSearch(value) {
       this.loadData(true);
     },
+    handleClickField(key, formData) {
+      console.log("key", key);
+      console.log("formData", formData);
+    },
+    handleClickItem(item) {
+      console.log("item", item);
+    },
+    goAddGood() {
+      uni.navigateTo({
+        url: "/pages/goods-enter/addGood",
+      });
+    },
   },
 };
 </script>
@@ -167,6 +244,11 @@ export default {
   min-height: 100vh;
   background-color: #f0f6fb;
   .container_main {
+    .head-box {
+      background-color: #fff;
+      padding-top: 20rpx;
+      padding-bottom: 32rpx;
+    }
     .search-box {
       background-color: rgba(191, 200, 219, 0.2);
       margin: 0 32rpx;
@@ -193,9 +275,8 @@ export default {
         }
       }
     }
-
     .content-box {
-      padding: 24rpx;
+      padding: 0 24rpx;
       &-val {
         border-radius: 16rpx 16rpx 0 0;
         overflow: hidden;
@@ -203,4 +284,82 @@ export default {
     }
   }
 }
+
+.content-list {
+  padding: 24rpx 0;
+  background-color: #fff;
+  margin-top: 24rpx;
+  border-radius: 16rpx;
+
+  .content-list-title {
+    font-family: "PingFang SC";
+    font-size: 32rpx;
+    font-style: normal;
+    font-weight: bold;
+    display: flex;
+    align-items: center;
+    position: relative;
+    padding-left: 50rpx;
+    margin-bottom: 24rpx;
+
+    &::after {
+      content: "";
+      display: block;
+      width: 6rpx;
+      height: 30rpx;
+      border-radius: 100px;
+      background: #0256ff;
+      position: absolute;
+      top: 50%;
+      left: 24rpx;
+      transform: translateY(-50%);
+    }
+
+    .content-list-title-tips {
+      color: #0256ff;
+      font-size: 24rpx;
+      font-weight: 400;
+    }
+  }
+}
+
+.dsh {
+  background-color: rgba(255, 59, 29, 0.2);
+  color: rgba(255, 59, 29, 1);
+  border-radius: 8rpx;
+}
+.zc {
+  background-color: rgba(0, 185, 123, 0.2);
+  color: rgba(0, 185, 123, 1);
+  border-radius: 8rpx;
+}
+.ybh {
+  background-color: rgba(225, 51, 15, 1);
+  color: #fff;
+  border-radius: 8rpx;
+}
+
+.footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 144rpx;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  .add-btn {
+    width: 700rpx;
+    height: 88rpx;
+    border-radius: 16rpx;
+    font-size: 36rpx;
+    font-weight: bold;
+    color: #fff;
+    background-color: #0256ff;
+    line-height: 88rpx;
+    text-align: center;
+  }
+}
 </style>

+ 1 - 1
pages/index/index.vue

@@ -147,7 +147,7 @@ export default {
           src: require("@/static/image/home/icon-fhrw.png"),
           text: "复核任务",
           num: 0,
-          url: "",
+          url: "/pages/audit-task/index",
         },
         {
           src: require("@/static/image/home/icon-hwlr.png"),