|
@@ -0,0 +1,681 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <view>
|
|
|
|
|
+ <u-form-item :label="label" :prop="inputProp" :required="required" :labelWidth="labelWidth">
|
|
|
|
|
+ <view class="selector-trigger" @tap.stop="openPicker" @click.stop="openPicker">
|
|
|
|
|
+ <u-input class="selector-input" :value="currentValue" :placeholder="displayPlaceholder" :readonly="readonly" :disabled="disabled"
|
|
|
|
|
+ @focus="openPicker" @click="openPicker" @tap="openPicker"></u-input>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </u-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="selector-mask" :class="{ show: visible }" @tap="closePicker"></view>
|
|
|
|
|
+ <view class="selector-panel" :class="{ show: visible }">
|
|
|
|
|
+ <view class="selector-header">
|
|
|
|
|
+ <view class="selector-action" @tap="closePicker">取消</view>
|
|
|
|
|
+ <view class="selector-title">{{ displayTitle }}</view>
|
|
|
|
|
+ <view v-if="showAddGoods" class="selector-action selector-action-wide" @tap.stop="openAddGoods">新增商品</view>
|
|
|
|
|
+ <view v-else class="selector-action selector-action-placeholder">取消</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="selector-search">
|
|
|
|
|
+ <u-search :show-action="false" v-model="keyword" :placeholder="displaySearchPlaceholder"></u-search>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <scroll-view :scroll-y="true" class="selector-list">
|
|
|
|
|
+ <view v-if="loading" class="selector-state">加载中...</view>
|
|
|
|
|
+ <view v-else-if="filteredList.length === 0" class="selector-state">{{ emptyText }}</view>
|
|
|
|
|
+ <view v-else class="selector-list-inner">
|
|
|
|
|
+ <view class="selector-card" v-for="item in filteredList" :key="item.id || item.tradeName"
|
|
|
|
|
+ @tap="selectItem(item)">
|
|
|
|
|
+ <view class="selector-name">{{ item.tradeName || '-' }}</view>
|
|
|
|
|
+ <view class="selector-meta" v-if="showStock">
|
|
|
|
|
+ <text>库存:{{ displayStock(item) }}</text>
|
|
|
|
|
+ <text v-if="item.company">单位:{{ item.company }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="selector-meta" v-if="item.brand || item.specification || (!showStock && item.company)">
|
|
|
|
|
+ <text v-if="item.brand">品牌:{{ item.brand }}</text>
|
|
|
|
|
+ <text v-if="item.specification">规格:{{ item.specification }}</text>
|
|
|
|
|
+ <text v-if="!showStock && item.company">单位:{{ item.company }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </scroll-view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="add-mask" :class="{ show: addVisible }" @tap="closeAddGoods"></view>
|
|
|
|
|
+ <view class="add-panel" :class="{ show: addVisible }">
|
|
|
|
|
+ <view class="selector-header">
|
|
|
|
|
+ <view class="selector-action" @tap="closeAddGoods">取消</view>
|
|
|
|
|
+ <view class="selector-title">新增商品</view>
|
|
|
|
|
+ <view class="selector-action" @tap.stop="submitAddGoods">{{ addLoading ? '保存中' : '保存' }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <scroll-view :scroll-y="true" class="add-body">
|
|
|
|
|
+ <u-form-item label="所属分类" :required="true" labelWidth="76px">
|
|
|
|
|
+ <view class="selector-trigger" @tap.stop="toggleCategoryList" @click.stop="toggleCategoryList">
|
|
|
|
|
+ <u-input class="selector-input" :value="addForm.parentName" placeholder="请选择所属分类"
|
|
|
|
|
+ readonly :disabled="isAddParentLocked"></u-input>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </u-form-item>
|
|
|
|
|
+ <u-form-item label="名称" :required="true" labelWidth="76px">
|
|
|
|
|
+ <u-input v-model="addForm.name" placeholder="请填写商品名称"></u-input>
|
|
|
|
|
+ </u-form-item>
|
|
|
|
|
+ <u-form-item label="品牌" labelWidth="76px">
|
|
|
|
|
+ <u-input v-model="addForm.brand" placeholder="请填写品牌"></u-input>
|
|
|
|
|
+ </u-form-item>
|
|
|
|
|
+ <u-form-item label="规格" labelWidth="76px">
|
|
|
|
|
+ <u-input v-model="addForm.specification" placeholder="请填写规格"></u-input>
|
|
|
|
|
+ </u-form-item>
|
|
|
|
|
+ <u-form-item label="单位" labelWidth="76px">
|
|
|
|
|
+ <u-input v-model="addForm.company" placeholder="请填写单位"></u-input>
|
|
|
|
|
+ </u-form-item>
|
|
|
|
|
+ </scroll-view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="category-mask" :class="{ show: categoryListVisible }" @tap="closeCategoryList"></view>
|
|
|
|
|
+ <view class="category-panel" :class="{ show: categoryListVisible }">
|
|
|
|
|
+ <view class="selector-header">
|
|
|
|
|
+ <view class="selector-action" @tap="closeCategoryList">取消</view>
|
|
|
|
|
+ <view class="selector-title">选择分类</view>
|
|
|
|
|
+ <view class="selector-action selector-action-placeholder">取消</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="selector-search">
|
|
|
|
|
+ <u-search :show-action="false" v-model="categoryKeyword" placeholder="搜索分类"></u-search>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <scroll-view :scroll-y="true" class="category-list">
|
|
|
|
|
+ <view v-if="categoryOptions.length === 0" class="selector-state category-state">暂无可选分类</view>
|
|
|
|
|
+ <view v-for="item in categoryOptions" :key="item.id" class="category-item"
|
|
|
|
|
+ @tap="selectCategory(item)">
|
|
|
|
|
+ {{ item.name || '-' }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </scroll-view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import MaterialTypeService from '@/api/psi/MaterialTypeService'
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: 'PsiGoodsSelector',
|
|
|
|
|
+ props: {
|
|
|
|
|
+ rowIndex: Number,
|
|
|
|
|
+ indexExperience: Number,
|
|
|
|
|
+ inputForm: {
|
|
|
|
|
+ type: Object,
|
|
|
|
|
+ default: () => ({})
|
|
|
|
|
+ },
|
|
|
|
|
+ rowPath: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: 'detailInfos'
|
|
|
|
|
+ },
|
|
|
|
|
+ valueFields: {
|
|
|
|
|
+ type: Array,
|
|
|
|
|
+ default: () => ['tradeName']
|
|
|
|
|
+ },
|
|
|
|
|
+ propField: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ label: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '物品名称'
|
|
|
|
|
+ },
|
|
|
|
|
+ labelWidth: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '68px'
|
|
|
|
|
+ },
|
|
|
|
|
+ placeholder: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ title: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ searchPlaceholder: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ emptyText: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '暂无可选物品'
|
|
|
|
|
+ },
|
|
|
|
|
+ parentIdField: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ parentNameField: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ parentRequiredText: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: '请先选择分类'
|
|
|
|
|
+ },
|
|
|
|
|
+ requireParent: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false
|
|
|
|
|
+ },
|
|
|
|
|
+ showStock: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: true
|
|
|
|
|
+ },
|
|
|
|
|
+ showAddGoods: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false
|
|
|
|
|
+ },
|
|
|
|
|
+ required: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: true
|
|
|
|
|
+ },
|
|
|
|
|
+ readonly: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: true
|
|
|
|
|
+ },
|
|
|
|
|
+ disabled: Boolean
|
|
|
|
|
+ },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ visible: false,
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ addVisible: false,
|
|
|
|
|
+ addLoading: false,
|
|
|
|
|
+ categoryListVisible: false,
|
|
|
|
|
+ keyword: '',
|
|
|
|
|
+ categoryKeyword: '',
|
|
|
|
|
+ rawMaterialList: [],
|
|
|
|
|
+ goodsList: [],
|
|
|
|
|
+ addForm: this.createAddForm(),
|
|
|
|
|
+ materialTypeService: null
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ actualIndex() {
|
|
|
|
|
+ if (this.rowIndex !== undefined && this.rowIndex !== null) {
|
|
|
|
|
+ return this.rowIndex
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.indexExperience
|
|
|
|
|
+ },
|
|
|
|
|
+ rows() {
|
|
|
|
|
+ return this.inputForm[this.rowPath] || []
|
|
|
|
|
+ },
|
|
|
|
|
+ currentRow() {
|
|
|
|
|
+ return this.rows[this.actualIndex] || {}
|
|
|
|
|
+ },
|
|
|
|
|
+ inputProp() {
|
|
|
|
|
+ const field = this.propField || this.valueFields[0] || ''
|
|
|
|
|
+ return field ? `${this.rowPath}[${this.actualIndex}].${field}` : ''
|
|
|
|
|
+ },
|
|
|
|
|
+ currentValue() {
|
|
|
|
|
+ for (let i = 0; i < this.valueFields.length; i++) {
|
|
|
|
|
+ const value = this.currentRow[this.valueFields[i]]
|
|
|
|
|
+ if (!this.isEmpty(value)) {
|
|
|
|
|
+ return value
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return ''
|
|
|
|
|
+ },
|
|
|
|
|
+ parentId() {
|
|
|
|
|
+ return this.parentIdField ? this.currentRow[this.parentIdField] : ''
|
|
|
|
|
+ },
|
|
|
|
|
+ currentParentName() {
|
|
|
|
|
+ if (this.parentNameField && !this.isEmpty(this.currentRow[this.parentNameField])) {
|
|
|
|
|
+ return this.currentRow[this.parentNameField]
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.currentRow.procurementType || this.currentRow.typeName || this.currentRow.categoryName || ''
|
|
|
|
|
+ },
|
|
|
|
|
+ isAddParentLocked() {
|
|
|
|
|
+ return !!this.parentIdField && !this.isEmpty(this.parentId)
|
|
|
|
|
+ },
|
|
|
|
|
+ displayPlaceholder() {
|
|
|
|
|
+ return this.placeholder || `请选择${this.label}`
|
|
|
|
|
+ },
|
|
|
|
|
+ displayTitle() {
|
|
|
|
|
+ return this.title || `选择${this.label}`
|
|
|
|
|
+ },
|
|
|
|
|
+ displaySearchPlaceholder() {
|
|
|
|
|
+ return this.searchPlaceholder || `搜索${this.label}`
|
|
|
|
|
+ },
|
|
|
|
|
+ filteredList() {
|
|
|
|
|
+ const keyword = (this.keyword || '').trim().toLowerCase()
|
|
|
|
|
+ if (!keyword) {
|
|
|
|
|
+ return this.goodsList
|
|
|
|
|
+ }
|
|
|
|
|
+ return this.goodsList.filter(item => (item.tradeName || '').toLowerCase().includes(keyword))
|
|
|
|
|
+ },
|
|
|
|
|
+ categoryOptions() {
|
|
|
|
|
+ const keyword = (this.categoryKeyword || '').trim().toLowerCase()
|
|
|
|
|
+ return this.flattenNodes(this.rawMaterialList).filter(item => {
|
|
|
|
|
+ const isGoods = String(item.infoType || item.info_type || '') === '1'
|
|
|
|
|
+ const name = item.name || item.tradeName || ''
|
|
|
|
|
+ return !isGoods && (!keyword || name.toLowerCase().includes(keyword))
|
|
|
|
|
+ }).map(item => ({
|
|
|
|
|
+ ...item,
|
|
|
|
|
+ name: item.name || item.tradeName || ''
|
|
|
|
|
+ }))
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ created() {
|
|
|
|
|
+ this.materialTypeService = new MaterialTypeService()
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ createAddForm() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ businessType: '',
|
|
|
|
|
+ infoType: '1',
|
|
|
|
|
+ name: '',
|
|
|
|
|
+ brand: '',
|
|
|
|
|
+ specification: '',
|
|
|
|
|
+ company: '',
|
|
|
|
|
+ parentId: '',
|
|
|
|
|
+ parentName: ''
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ isEmpty(value) {
|
|
|
|
|
+ if (value === null || value === undefined) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ if (typeof value === 'string' && value.trim() === '') {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ if (Array.isArray(value) && value.length === 0) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ return false
|
|
|
|
|
+ },
|
|
|
|
|
+ displayStock(item) {
|
|
|
|
|
+ if (!this.isEmpty(item.currentInventory)) {
|
|
|
|
|
+ return item.currentInventory
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.isEmpty(item.surplusNumber)) {
|
|
|
|
|
+ return item.surplusNumber
|
|
|
|
|
+ }
|
|
|
|
|
+ return '0'
|
|
|
|
|
+ },
|
|
|
|
|
+ async openPicker() {
|
|
|
|
|
+ if (this.disabled) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.visible) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.requireParent && this.isEmpty(this.parentId)) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: this.parentRequiredText,
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.visible = true
|
|
|
|
|
+ this.keyword = ''
|
|
|
|
|
+ await this.loadGoodsList()
|
|
|
|
|
+ },
|
|
|
|
|
+ closePicker() {
|
|
|
|
|
+ this.visible = false
|
|
|
|
|
+ this.closeAddGoods()
|
|
|
|
|
+ },
|
|
|
|
|
+ async loadGoodsList() {
|
|
|
|
|
+ this.loading = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await this.materialTypeService.cgList()
|
|
|
|
|
+ this.rawMaterialList = data || []
|
|
|
|
|
+ this.goodsList = this.flattenNodes(this.rawMaterialList).filter(item => {
|
|
|
|
|
+ const itemParentId = item.parentId || item.parent_id || ''
|
|
|
|
|
+ const isGoods = String(item.infoType || item.info_type || '') === '1'
|
|
|
|
|
+ const matchParent = !this.parentIdField || this.isEmpty(this.parentId) ||
|
|
|
|
|
+ String(itemParentId) === String(this.parentId)
|
|
|
|
|
+ return isGoods && matchParent
|
|
|
|
|
+ }).map(item => ({
|
|
|
|
|
+ ...item,
|
|
|
|
|
+ tradeName: item.tradeName || item.name || ''
|
|
|
|
|
+ }))
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ this.goodsList = []
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: `${this.label}数据加载失败`,
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ this.loading = false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ flattenNodes(nodes, result = []) {
|
|
|
|
|
+ ;(nodes || []).forEach(node => {
|
|
|
|
|
+ result.push(node)
|
|
|
|
|
+ if (node.children && node.children.length) {
|
|
|
|
|
+ this.flattenNodes(node.children, result)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ return result
|
|
|
|
|
+ },
|
|
|
|
|
+ selectItem(item) {
|
|
|
|
|
+ this.$emit('selected', {
|
|
|
|
|
+ index: this.actualIndex,
|
|
|
|
|
+ item
|
|
|
|
|
+ })
|
|
|
|
|
+ this.closePicker()
|
|
|
|
|
+ },
|
|
|
|
|
+ async openAddGoods() {
|
|
|
|
|
+ if (this.addLoading) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.addForm = this.createAddForm()
|
|
|
|
|
+ if (this.isAddParentLocked) {
|
|
|
|
|
+ this.addForm.parentId = this.parentId
|
|
|
|
|
+ this.addForm.parentName = this.currentParentName
|
|
|
|
|
+ }
|
|
|
|
|
+ this.categoryKeyword = ''
|
|
|
|
|
+ this.categoryListVisible = false
|
|
|
|
|
+ this.addVisible = true
|
|
|
|
|
+ if (this.rawMaterialList.length === 0) {
|
|
|
|
|
+ await this.loadMaterialListForAdd()
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ closeAddGoods() {
|
|
|
|
|
+ if (this.addLoading) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.addVisible = false
|
|
|
|
|
+ this.categoryListVisible = false
|
|
|
|
|
+ },
|
|
|
|
|
+ async loadMaterialListForAdd() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await this.materialTypeService.cgList()
|
|
|
|
|
+ this.rawMaterialList = data || []
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ this.rawMaterialList = []
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '分类数据加载失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ toggleCategoryList() {
|
|
|
|
|
+ if (this.isAddParentLocked) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.categoryListVisible = !this.categoryListVisible
|
|
|
|
|
+ },
|
|
|
|
|
+ closeCategoryList() {
|
|
|
|
|
+ this.categoryListVisible = false
|
|
|
|
|
+ },
|
|
|
|
|
+ selectCategory(item) {
|
|
|
|
|
+ this.addForm.parentId = item.id
|
|
|
|
|
+ this.addForm.parentName = item.name || item.tradeName || ''
|
|
|
|
|
+ this.categoryListVisible = false
|
|
|
|
|
+ },
|
|
|
|
|
+ async submitAddGoods() {
|
|
|
|
|
+ if (this.addLoading) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.isEmpty(this.addForm.parentId)) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '请选择所属分类',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.isEmpty(this.addForm.name)) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '请填写商品名称',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const submitData = {
|
|
|
|
|
+ ...this.addForm,
|
|
|
|
|
+ infoType: '1'
|
|
|
|
|
+ }
|
|
|
|
|
+ delete submitData.parentName
|
|
|
|
|
+ this.addLoading = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await this.materialTypeService.save(submitData)
|
|
|
|
|
+ const result = this.getResponseData(data)
|
|
|
|
|
+ if (typeof result === 'string' && result.indexOf('不能新增') > -1) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: result,
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '保存成功',
|
|
|
|
|
+ icon: 'success'
|
|
|
|
|
+ })
|
|
|
|
|
+ this.addVisible = false
|
|
|
|
|
+ await this.loadGoodsList()
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '商品保存失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ this.addLoading = false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ getResponseData(data) {
|
|
|
|
|
+ if (data && Object.prototype.hasOwnProperty.call(data, 'data')) {
|
|
|
|
|
+ return data.data
|
|
|
|
|
+ }
|
|
|
|
|
+ return data
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.selector-mask {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ inset: 0;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.35);
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ visibility: hidden;
|
|
|
|
|
+ transition: all 0.25s ease;
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-trigger {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-input {
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-mask.show {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ visibility: visible;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.add-mask {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ inset: 0;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.35);
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ visibility: hidden;
|
|
|
|
|
+ transition: all 0.25s ease;
|
|
|
|
|
+ z-index: 1002;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.add-mask.show {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ visibility: visible;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-panel {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ height: 68vh;
|
|
|
|
|
+ background: #f7f9fc;
|
|
|
|
|
+ border-radius: 28rpx 28rpx 0 0;
|
|
|
|
|
+ transform: translateY(100%);
|
|
|
|
|
+ transition: transform 0.25s ease;
|
|
|
|
|
+ z-index: 1001;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-panel.show {
|
|
|
|
|
+ transform: translateY(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.add-panel {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ height: 78vh;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 28rpx 28rpx 0 0;
|
|
|
|
|
+ transform: translateY(100%);
|
|
|
|
|
+ transition: transform 0.25s ease;
|
|
|
|
|
+ z-index: 1003;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.add-panel.show {
|
|
|
|
|
+ transform: translateY(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.add-body {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: 0;
|
|
|
|
|
+ padding: 18rpx 28rpx 40rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-mask {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ inset: 0;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.35);
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ visibility: hidden;
|
|
|
|
|
+ transition: all 0.25s ease;
|
|
|
|
|
+ z-index: 1004;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-mask.show {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ visibility: visible;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-panel {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ height: 62vh;
|
|
|
|
|
+ background: #f7f9fc;
|
|
|
|
|
+ border-radius: 28rpx 28rpx 0 0;
|
|
|
|
|
+ transform: translateY(100%);
|
|
|
|
|
+ transition: transform 0.25s ease;
|
|
|
|
|
+ z-index: 1005;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-panel.show {
|
|
|
|
|
+ transform: translateY(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-list {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: 0;
|
|
|
|
|
+ padding: 16rpx 24rpx 32rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-item {
|
|
|
|
|
+ margin-bottom: 14rpx;
|
|
|
|
|
+ padding: 22rpx 24rpx;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #1f2937;
|
|
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.category-state {
|
|
|
|
|
+ padding-top: 120rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 28rpx 32rpx 16rpx;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-bottom: 1rpx solid #eef2f7;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-title {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #1f2937;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-action {
|
|
|
|
|
+ min-width: 80rpx;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #2979ff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-action-wide {
|
|
|
|
|
+ min-width: 128rpx;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-action-placeholder {
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-search {
|
|
|
|
|
+ padding: 20rpx 24rpx 8rpx;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-list {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: 0;
|
|
|
|
|
+ padding: 16rpx 24rpx 32rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-list-inner {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-state {
|
|
|
|
|
+ padding-top: 120rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #94a3b8;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-card {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
|
+ padding: 24rpx;
|
|
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-name {
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #0f172a;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-meta {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ margin-top: 10rpx;
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #64748b;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|