Commit 5e8271276bef7160bc5a305d58b2c99d77d731c0

Authored by 李宇
1 parent d57a2bdf

退卡

antis-ncc-admin/src/views/lqHytkHytk/Form copy.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="!dataForm.id ? '新建' : isDetail ? '详情':'编辑'" :close-on-click-modal="false" :visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="90%">
  3 + <el-row :gutter="15" class="" >
  4 + <el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right" :disabled="!!isDetail" :rules="rules">
  5 + <el-col :span="8" v-if="false" >
  6 + <el-form-item label="退卡编号" prop="id">
  7 + <el-input v-model="dataForm.id" placeholder="请输入" clearable :style='{"width":"100%"}' >
  8 + </el-input>
  9 + </el-form-item>
  10 + </el-col>
  11 + <el-col :span="8">
  12 + <el-form-item label="门店" prop="md">
  13 + <el-select v-model="dataForm.md" placeholder="请选择" clearable :style='{"width":"100%"}' filterable >
  14 + <el-option v-for="(item, index) in mdOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option>
  15 + </el-select>
  16 + </el-form-item>
  17 + </el-col>
  18 + <el-col :span="8">
  19 + <el-form-item label="门店编号" prop="mcbh">
  20 + <el-input v-model="dataForm.mcbh" placeholder="请输入" clearable :style='{"width":"100%"}' >
  21 + </el-input>
  22 + </el-form-item>
  23 + </el-col>
  24 + <el-col :span="8">
  25 + <el-form-item label="门店名称" prop="mdmc">
  26 + <el-input v-model="dataForm.mdmc" placeholder="请输入" clearable :style='{"width":"100%"}' >
  27 + </el-input>
  28 + </el-form-item>
  29 + </el-col>
  30 + <el-col :span="8">
  31 + <el-form-item label="会员" prop="hy">
  32 + <el-select v-model="dataForm.hy" placeholder="请选择" clearable :style='{"width":"100%"}' filterable >
  33 + <el-option v-for="(item, index) in hyOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option>
  34 + </el-select>
  35 + </el-form-item>
  36 + </el-col>
  37 + <el-col :span="8">
  38 + <el-form-item label="会员姓名" prop="hyxm">
  39 + <el-input v-model="dataForm.hyxm" placeholder="请输入" clearable :style='{"width":"100%"}' >
  40 + </el-input>
  41 + </el-form-item>
  42 + </el-col>
  43 + <el-col :span="8">
  44 + <el-form-item label="会员账号" prop="hyzh">
  45 + <el-input v-model="dataForm.hyzh" placeholder="请输入" clearable :style='{"width":"100%"}' >
  46 + </el-input>
  47 + </el-form-item>
  48 + </el-col>
  49 + <el-col :span="8">
  50 + <el-form-item label="健康师" prop="jks">
  51 + <user-select v-model="dataForm.jks" placeholder="请选择" clearable >
  52 + </user-select>
  53 + </el-form-item>
  54 + </el-col>
  55 + <el-col :span="8">
  56 + <el-form-item label="健康师账号" prop="jkszh">
  57 + <el-input v-model="dataForm.jkszh" placeholder="请输入" clearable :style='{"width":"100%"}' >
  58 + </el-input>
  59 + </el-form-item>
  60 + </el-col>
  61 + <el-col :span="8">
  62 + <el-form-item label="健康师姓名" prop="jksxm">
  63 + <el-input v-model="dataForm.jksxm" placeholder="请输入" clearable :style='{"width":"100%"}' >
  64 + </el-input>
  65 + </el-form-item>
  66 + </el-col>
  67 + <el-col :span="24">
  68 + <el-form-item label="备注" prop="bz">
  69 + <el-input v-model="dataForm.bz" placeholder="请输入" show-word-limit :style='{"width":"100%"}' type='textarea' :autosize='{"minRows":4,"maxRows":4}' >
  70 + </el-input>
  71 + </el-form-item>
  72 + </el-col>
  73 + <el-col :span="24" v-if="false" >
  74 + <el-form-item label="退卡品项" prop="tkpx">
  75 + <el-input v-model="dataForm.tkpx" placeholder="请输入" clearable :style='{"width":"100%"}' >
  76 + </el-input>
  77 + </el-form-item>
  78 + </el-col>
  79 + <el-col :span="24" v-if="false" >
  80 + <el-form-item label="退卡时间" prop="tksj">
  81 + <el-input v-model="dataForm.tksj" placeholder="系统自动生成" readonly >
  82 + </el-input>
  83 + </el-form-item>
  84 + </el-col>
  85 + <el-col :span="24" v-if="false" >
  86 + <el-form-item label="退卡人" prop="tkr">
  87 + <el-input v-model="dataForm.tkr" placeholder="系统自动生成" readonly >
  88 + </el-input>
  89 + </el-form-item>
  90 + </el-col>
  91 + <el-col :span="24">
  92 + <el-form-item label-width="0">
  93 + <el-table :data="dataForm.lqHytkMxList" size='mini'>
  94 + <el-table-column type="index" width="50" label="序号" align="center" />
  95 + <el-table-column prop="id" label="明细编号" v-if="false">
  96 + <template slot-scope="scope">
  97 + <el-input v-model="scope.row.id" placeholder="请输入" clearable ></el-input>
  98 + </template>
  99 + </el-table-column>
  100 + <el-table-column prop="gltkbh" label="关联退卡编号" v-if="false">
  101 + <template slot-scope="scope">
  102 + <el-input v-model="scope.row.gltkbh" placeholder="请输入" clearable ></el-input>
  103 + </template>
  104 + </el-table-column>
  105 + <el-table-column prop="px" label="品项">
  106 + <template slot-scope="scope">
  107 + <el-select v-model="scope.row.px" placeholder="请选择" clearable >
  108 + <el-option v-for="(item, index) in pxOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option>
  109 + </el-select>
  110 + </template>
  111 + </el-table-column>
  112 + <el-table-column prop="mc" label="品项名称">
  113 + <template slot-scope="scope">
  114 + <el-input v-model="scope.row.mc" placeholder="请输入" clearable ></el-input>
  115 + </template>
  116 + </el-table-column>
  117 + <el-table-column prop="tkje" label="退款金额">
  118 + <template slot-scope="scope">
  119 + <el-input v-model="scope.row.tkje" placeholder="请输入" clearable ></el-input>
  120 + </template>
  121 + </el-table-column>
  122 + <el-table-column prop="cs" label="次数">
  123 + <template slot-scope="scope">
  124 + <el-input v-model="scope.row.cs" placeholder="请输入" clearable ></el-input>
  125 + </template>
  126 + </el-table-column>
  127 + <el-table-column prop="dchk" label="单次耗卡">
  128 + <template slot-scope="scope">
  129 + <el-input v-model="scope.row.dchk" placeholder="请输入" clearable ></el-input>
  130 + </template>
  131 + </el-table-column>
  132 + <el-table-column prop="fssj" label="发生时间" v-if="false">
  133 + <template slot-scope="scope">
  134 + <el-input v-model="scope.row.fssj" placeholder="请输入" clearable ></el-input>
  135 + </template>
  136 + </el-table-column>
  137 + <el-table-column label="操作" width="50">
  138 + <template slot-scope="scope">
  139 + <el-button size="mini" type="text" class="NCC-table-delBtn" @click="handleDelLqHytkMxEntityList(scope.$index)">删除</el-button>
  140 + </template>
  141 + </el-table-column>
  142 + </el-table>
  143 + <div class="table-actions" @click="addHandleLqHytkMxEntityList()">
  144 + <el-button type="text" icon="el-icon-plus">新增</el-button>
  145 + </div>
  146 + </el-form-item>
  147 + </el-col>
  148 + </el-form>
  149 + </el-row>
  150 + <span slot="footer" class="dialog-footer">
  151 + <el-button @click="visible = false">取 消</el-button>
  152 + <el-button type="primary" @click="dataFormSubmit()" v-if="!isDetail">确 定</el-button>
  153 + </span>
  154 + </el-dialog>
  155 +</template>
  156 +<script>
  157 + import request from '@/utils/request'
  158 + import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
  159 + import { previewDataInterface } from '@/api/systemData/dataInterface'
  160 + export default {
  161 + components: {},
  162 + props: [],
  163 + data() {
  164 + return {
  165 + loading: false,
  166 + visible: false,
  167 + isDetail: false,
  168 + dataForm: {
  169 + id:'',
  170 + id:undefined,
  171 + md:undefined,
  172 + mcbh:undefined,
  173 + mdmc:undefined,
  174 + hy:undefined,
  175 + hyxm:undefined,
  176 + hyzh:undefined,
  177 + jks:undefined,
  178 + jkszh:undefined,
  179 + jksxm:undefined,
  180 + bz:undefined,
  181 + tkpx:undefined,
  182 + tksj:undefined,
  183 + tkr:undefined,
  184 + lqHytkMxList:[],
  185 + },
  186 + rules: {
  187 + },
  188 + mdOptions : [],
  189 + hyOptions : [],
  190 + pxOptions : [],
  191 + }
  192 + },
  193 + computed: {},
  194 + watch: {},
  195 + created() {
  196 + this.getmdOptions();
  197 + this.gethyOptions();
  198 + this.getpxOptions();
  199 + },
  200 + mounted() {
  201 + },
  202 + methods: {
  203 + getmdOptions(){
  204 + previewDataInterface('730960205902251269').then(res => {
  205 + this.mdOptions = res.data
  206 + });
  207 + },
  208 + gethyOptions(){
  209 + previewDataInterface('730998109110273285').then(res => {
  210 + this.hyOptions = res.data
  211 + });
  212 + },
  213 + getpxOptions(){
  214 + previewDataInterface('730971133356016901').then(res => {
  215 + this.pxOptions = res.data
  216 + });
  217 + },
  218 + goBack() {
  219 + this.$emit('refresh')
  220 + },
  221 + init(id, isDetail) {
  222 + this.dataForm.id = id || 0;
  223 + this.visible = true;
  224 + this.isDetail = isDetail || false;
  225 + this.$nextTick(() => {
  226 + this.$refs['elForm'].resetFields();
  227 + if (this.dataForm.id) {
  228 + request({
  229 + url: '/api/Extend/LqHytkHytk/' + this.dataForm.id,
  230 + method: 'get'
  231 + }).then(res =>{
  232 + this.dataForm = res.data;
  233 + })
  234 + }
  235 + })
  236 + },
  237 + dataFormSubmit() {
  238 + this.$refs['elForm'].validate((valid) => {
  239 + if (valid) {
  240 + if (!this.dataForm.id) {
  241 + request({
  242 + url: `/api/Extend/LqHytkHytk`,
  243 + method: 'post',
  244 + data: this.dataForm,
  245 + }).then((res) => {
  246 + this.$message({
  247 + message: res.msg,
  248 + type: 'success',
  249 + duration: 1000,
  250 + onClose: () => {
  251 + this.visible = false,
  252 + this.$emit('refresh', true)
  253 + }
  254 + })
  255 + })
  256 + } else {
  257 + request({
  258 + url: '/api/Extend/LqHytkHytk/' + this.dataForm.id,
  259 + method: 'PUT',
  260 + data: this.dataForm
  261 + }).then((res) => {
  262 + this.$message({
  263 + message: res.msg,
  264 + type: 'success',
  265 + duration: 1000,
  266 + onClose: () => {
  267 + this.visible = false
  268 + this.$emit('refresh', true)
  269 + }
  270 + })
  271 + })
  272 + }
  273 + }
  274 + })
  275 + },
  276 + addHandleLqHytkMxEntityList() {
  277 + let item = {
  278 + id:undefined,
  279 + gltkbh:undefined,
  280 + px:undefined,
  281 + mc:undefined,
  282 + tkje:undefined,
  283 + cs:undefined,
  284 + dchk:undefined,
  285 + fssj:undefined,
  286 + }
  287 + this.dataForm.lqHytkMxList.push(item)
  288 + },
  289 + handleDelLqHytkMxEntityList(index) {
  290 + this.dataForm.lqHytkMxList.splice(index, 1);
  291 + },
  292 + }
  293 + }
  294 +</script>
antis-ncc-admin/src/views/lqHytkHytk/Form.vue
@@ -8,141 +8,232 @@ @@ -8,141 +8,232 @@
8 </el-input> 8 </el-input>
9 </el-form-item> 9 </el-form-item>
10 </el-col> 10 </el-col>
11 - <el-col :span="8">  
12 - <el-form-item label="门店" prop="md">  
13 - <el-select v-model="dataForm.md" placeholder="请选择" clearable :style='{"width":"100%"}' filterable > 11 + <el-col :span="6">
  12 + <el-form-item label="门店" prop="md" required>
  13 + <el-select v-model="dataForm.md" placeholder="请选择" clearable :style='{"width":"100%"}' filterable @change="handleMdChange">
14 <el-option v-for="(item, index) in mdOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> 14 <el-option v-for="(item, index) in mdOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option>
15 </el-select> 15 </el-select>
16 </el-form-item> 16 </el-form-item>
17 </el-col> 17 </el-col>
18 - <el-col :span="8">  
19 - <el-form-item label="门店编号" prop="mcbh">  
20 - <el-input v-model="dataForm.mcbh" placeholder="请输入" clearable :style='{"width":"100%"}' > 18 + <el-col :span="8" v-if="false">
  19 + <el-form-item label="门店编号" prop="mdbh">
  20 + <el-input v-model="dataForm.mdbh" placeholder="自动填充" clearable readonly :style='{"width":"100%"}' >
21 </el-input> 21 </el-input>
22 </el-form-item> 22 </el-form-item>
23 </el-col> 23 </el-col>
24 - <el-col :span="8"> 24 + <el-col :span="8" v-if="false">
25 <el-form-item label="门店名称" prop="mdmc"> 25 <el-form-item label="门店名称" prop="mdmc">
26 - <el-input v-model="dataForm.mdmc" placeholder="请输入" clearable :style='{"width":"100%"}' > 26 + <el-input v-model="dataForm.mdmc" placeholder="自动填充" clearable readonly :style='{"width":"100%"}' >
27 </el-input> 27 </el-input>
28 </el-form-item> 28 </el-form-item>
29 </el-col> 29 </el-col>
30 - <el-col :span="8">  
31 - <el-form-item label="会员" prop="hy">  
32 - <el-select v-model="dataForm.hy" placeholder="请选择" clearable :style='{"width":"100%"}' filterable > 30 + <el-col :span="6">
  31 + <el-form-item label="会员" prop="hy" required>
  32 + <el-select v-model="dataForm.hy" placeholder="请选择" clearable :style='{"width":"100%"}' filterable @change="handleHyChange">
33 <el-option v-for="(item, index) in hyOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> 33 <el-option v-for="(item, index) in hyOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option>
34 </el-select> 34 </el-select>
35 </el-form-item> 35 </el-form-item>
36 </el-col> 36 </el-col>
37 - <el-col :span="8">  
38 - <el-form-item label="会员姓名" prop="hyxm">  
39 - <el-input v-model="dataForm.hyxm" placeholder="请输入" clearable :style='{"width":"100%"}' > 37 + <el-col :span="8" v-if="false">
  38 + <el-form-item label="会员姓名" prop="hymc">
  39 + <el-input v-model="dataForm.hymc" placeholder="自动填充" clearable readonly :style='{"width":"100%"}' >
40 </el-input> 40 </el-input>
41 </el-form-item> 41 </el-form-item>
42 </el-col> 42 </el-col>
43 - <el-col :span="8"> 43 + <el-col :span="8" v-if="false">
44 <el-form-item label="会员账号" prop="hyzh"> 44 <el-form-item label="会员账号" prop="hyzh">
45 - <el-input v-model="dataForm.hyzh" placeholder="请输入" clearable :style='{"width":"100%"}' > 45 + <el-input v-model="dataForm.hyzh" placeholder="自动填充" clearable readonly :style='{"width":"100%"}' >
46 </el-input> 46 </el-input>
47 </el-form-item> 47 </el-form-item>
48 </el-col> 48 </el-col>
49 - <el-col :span="8">  
50 - <el-form-item label="健康师" prop="jks">  
51 - <user-select v-model="dataForm.jks" placeholder="请选择" clearable >  
52 - </user-select>  
53 - </el-form-item>  
54 - </el-col>  
55 - <el-col :span="8">  
56 - <el-form-item label="健康师账号" prop="jkszh">  
57 - <el-input v-model="dataForm.jkszh" placeholder="请输入" clearable :style='{"width":"100%"}' > 49 + <el-col :span="6">
  50 + <el-form-item label="退款金额" prop="tkje">
  51 + <el-input v-model="dataForm.tkje" placeholder="自动计算" clearable readonly :style='{"width":"100%"}'>
  52 + <template slot="append">元</template>
58 </el-input> 53 </el-input>
59 </el-form-item> 54 </el-form-item>
60 </el-col> 55 </el-col>
61 - <el-col :span="8">  
62 - <el-form-item label="健康师姓名" prop="jksxm">  
63 - <el-input v-model="dataForm.jksxm" placeholder="请输入" clearable :style='{"width":"100%"}' >  
64 - </el-input>  
65 - </el-form-item>  
66 - </el-col>  
67 - <el-col :span="24">  
68 - <el-form-item label="备注" prop="bz">  
69 - <el-input v-model="dataForm.bz" placeholder="请输入" show-word-limit :style='{"width":"100%"}' type='textarea' :autosize='{"minRows":4,"maxRows":4}' > 56 + <el-col :span="6">
  57 + <el-form-item label="手工费用" prop="sgfy">
  58 + <el-input v-model="dataForm.sgfy" placeholder="自动计算" clearable readonly :style='{"width":"100%"}'>
  59 + <template slot="append">元</template>
70 </el-input> 60 </el-input>
71 </el-form-item> 61 </el-form-item>
72 </el-col> 62 </el-col>
  63 + <el-col :span="16"></el-col>
73 <el-col :span="24" v-if="false" > 64 <el-col :span="24" v-if="false" >
74 <el-form-item label="退卡品项" prop="tkpx"> 65 <el-form-item label="退卡品项" prop="tkpx">
75 <el-input v-model="dataForm.tkpx" placeholder="请输入" clearable :style='{"width":"100%"}' > 66 <el-input v-model="dataForm.tkpx" placeholder="请输入" clearable :style='{"width":"100%"}' >
76 </el-input> 67 </el-input>
77 </el-form-item> 68 </el-form-item>
78 </el-col> 69 </el-col>
79 - <el-col :span="24" v-if="false" >  
80 - <el-form-item label="退卡时间" prop="tksj">  
81 - <el-input v-model="dataForm.tksj" placeholder="系统自动生成" readonly >  
82 - </el-input>  
83 - </el-form-item>  
84 - </el-col>  
85 - <el-col :span="24" v-if="false" >  
86 - <el-form-item label="退卡人" prop="tkr">  
87 - <el-input v-model="dataForm.tkr" placeholder="系统自动生成" readonly >  
88 - </el-input>  
89 - </el-form-item>  
90 - </el-col>  
91 <el-col :span="24"> 70 <el-col :span="24">
92 - <el-form-item label-width="0">  
93 - <el-table :data="dataForm.lqHytkMxList" size='mini'>  
94 - <el-table-column type="index" width="50" label="序号" align="center" />  
95 - <el-table-column prop="id" label="明细编号" v-if="false">  
96 - <template slot-scope="scope">  
97 - <el-input v-model="scope.row.id" placeholder="请输入" clearable ></el-input>  
98 - </template>  
99 - </el-table-column>  
100 - <el-table-column prop="gltkbh" label="关联退卡编号" v-if="false">  
101 - <template slot-scope="scope">  
102 - <el-input v-model="scope.row.gltkbh" placeholder="请输入" clearable ></el-input>  
103 - </template>  
104 - </el-table-column>  
105 - <el-table-column prop="px" label="品项">  
106 - <template slot-scope="scope">  
107 - <el-select v-model="scope.row.px" placeholder="请选择" clearable > 71 + <el-form-item label-width="0">
  72 + <div class="table-header">
  73 + <span class="table-title">品项明细</span>
  74 + <el-button v-if="!dataForm.id" type="warning" size="mini" icon="el-icon-plus" @click="addHandleLqXhPxmxEntityList()">新增品项</el-button>
  75 + </div>
  76 +
  77 + <!-- 品项列表 -->
  78 + <div class="px-list-container">
  79 + <div v-for="(px, pxIndex) in dataForm.lqHytkMxList" :key="pxIndex" class="px-item">
  80 + <!-- 品项基本信息 -->
  81 + <div class="px-basic-info">
  82 + <div class="px-item-header">
  83 + <span class="px-item-title">品项明细</span>
  84 + <el-button v-if="!dataForm.id"size="mini" type="danger" icon="el-icon-delete" @click="handleDelLqXhPxmxEntityList(pxIndex)">删除</el-button>
  85 + </div>
  86 +
  87 + <!-- 品项选择 -->
  88 + <div class="px-select-row">
  89 + <el-select v-model="px.px" placeholder="请选择品项" clearable filterable @change="handlePxChange(pxIndex, px)" style="width: 200px;">
108 <el-option v-for="(item, index) in pxOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option> 90 <el-option v-for="(item, index) in pxOptions" :key="index" :label="item.fullName" :value="item.id" :disabled="item.disabled"></el-option>
109 </el-select> 91 </el-select>
110 - </template>  
111 - </el-table-column>  
112 - <el-table-column prop="mc" label="品项名称">  
113 - <template slot-scope="scope">  
114 - <el-input v-model="scope.row.mc" placeholder="请输入" clearable ></el-input>  
115 - </template>  
116 - </el-table-column>  
117 - <el-table-column prop="tkje" label="退款金额">  
118 - <template slot-scope="scope">  
119 - <el-input v-model="scope.row.tkje" placeholder="请输入" clearable ></el-input>  
120 - </template>  
121 - </el-table-column>  
122 - <el-table-column prop="cs" label="次数">  
123 - <template slot-scope="scope">  
124 - <el-input v-model="scope.row.cs" placeholder="请输入" clearable ></el-input>  
125 - </template>  
126 - </el-table-column>  
127 - <el-table-column prop="dchk" label="单次耗卡">  
128 - <template slot-scope="scope">  
129 - <el-input v-model="scope.row.dchk" placeholder="请输入" clearable ></el-input>  
130 - </template>  
131 - </el-table-column>  
132 - <el-table-column prop="fssj" label="发生时间" v-if="false">  
133 - <template slot-scope="scope">  
134 - <el-input v-model="scope.row.fssj" placeholder="请输入" clearable ></el-input>  
135 - </template>  
136 - </el-table-column>  
137 - <el-table-column label="操作" width="50">  
138 - <template slot-scope="scope">  
139 - <el-button size="mini" type="text" class="NCC-table-delBtn" @click="handleDelLqHytkMxEntityList(scope.$index)">删除</el-button>  
140 - </template>  
141 - </el-table-column>  
142 - </el-table>  
143 - <div class="table-actions" @click="addHandleLqHytkMxEntityList()">  
144 - <el-button type="text" icon="el-icon-plus">新增</el-button> 92 + </div>
  93 +
  94 + <!-- 品项详细信息 -->
  95 + <div class="px-detail-info" v-if="px.px">
  96 + <div class="px-detail-row">
  97 + <div class="px-detail-item">
  98 + <span class="px-detail-label">品项名称:</span>
  99 + <span class="px-detail-value">{{ px.pxmc || '未选择' }}</span>
  100 + </div>
  101 + <div class="px-detail-item">
  102 + <span class="px-detail-label">单价:</span>
  103 + <span class="px-detail-value">¥{{ px.pxjg || 0 }}</span>
  104 + </div>
  105 + <div class="px-detail-item">
  106 + <span class="px-detail-label">已消费:</span>
  107 + <span class="px-detail-value">{{ px.yxf || 0 }}</span>
  108 + </div>
  109 + <div class="px-detail-item">
  110 + <span class="px-detail-label">总购买:</span>
  111 + <span class="px-detail-value">{{ px.zgm || 1 }}</span>
  112 + </div>
  113 + <div class="px-detail-item">
  114 + <span class="px-detail-label">剩余:</span>
  115 + <span class="px-detail-value">{{ (px.zgm || 1) - (px.yxf || 0) }}</span>
  116 + </div>
  117 + <div class="px-detail-item">
  118 + <span class="px-detail-label">类型:</span>
  119 + <span class="px-detail-value">{{ px.ly || '购买' }}</span>
  120 + </div>
  121 +
  122 + </div>
  123 +
  124 + <!-- 消费数量输入 -->
  125 + <div class="px-consumption-row">
  126 + <el-input-number v-model="px.projectNumber" :min="1" :max="getRemainingCount(px)" placeholder="消费数量" size="mini" style="width: 120px;" @change="onProjectNumberChange"></el-input-number>
  127 + </div>
  128 + </div>
  129 + </div>
  130 +
  131 + <!-- 健康师业绩区域 -->
  132 + <div class="px-staff-section">
  133 + <div class="px-staff-header">
  134 + <span class="px-staff-title">健康师业绩</span>
  135 + <el-button v-if="!dataForm.id" size="mini" type="success" icon="el-icon-plus" @click="addPxJks(pxIndex)">添加健康师</el-button>
  136 + </div>
  137 + <div class="px-staff-list">
  138 + <div v-for="(jks, jksIndex) in px.lqHytkJksyjList" :key="jksIndex" class="px-staff-row">
  139 + <div class="px-staff-item">
  140 + <div class="px-staff-fields">
  141 + <div class="px-staff-field">
  142 + <label>健康师</label>
  143 + <el-select v-model="jks.jks" placeholder="选择健康师" clearable filterable size="mini" style="width: 200px;" @change="handleJksChange(pxIndex, jksIndex, jks)">
  144 + <el-option v-for="(item, index) in jksOptions" :key="index" :label="item.fullName" :value="item.id"></el-option>
  145 + </el-select>
  146 + </div>
  147 + <div class="px-staff-field">
  148 + <label>业绩</label>
  149 + <el-input v-model="jks.jksyj" placeholder="请输入业绩" size="mini" style="width: 120px;" @input="formatPxStaffNumber(pxIndex, jksIndex, 'jksyj', 'lqHytkJksyjList')">
  150 + <template slot="append">元</template>
  151 + </el-input>
  152 + </div>
  153 + <div class="px-staff-field">
  154 + <label>手工费</label>
  155 + <el-input v-model="jks.laborCost" placeholder="手工费" size="mini" style="width: 120px;" @input="formatPxStaffNumber(pxIndex, jksIndex, 'laborCost', 'lqHytkJksyjList')">
  156 + <template slot="append">元</template>
  157 + </el-input>
  158 + </div>
  159 + <div class="px-staff-field">
  160 + <label>次数</label>
  161 + <el-input-number v-model="jks.kdpxNumber" :min="1" :max="999" placeholder="次数" size="mini" style="width: 120px;"></el-input-number>
  162 + </div>
  163 + <div class="px-staff-field" v-if="!dataForm.id">
  164 + <el-button size="mini" type="danger" icon="el-icon-delete" @click="removePxJks(pxIndex, jksIndex)">删除</el-button>
  165 + </div>
  166 + </div>
  167 + </div>
  168 + </div>
  169 + </div>
  170 + </div>
  171 +
  172 + <!-- 科技部老师业绩区域 - 仅当品项类型为科美时显示 -->
  173 + <div class="px-staff-section" v-if="px.qt2 === '科美'" :key="'kjb-' + pxIndex + '-' + px.qt2">
  174 + <div class="px-staff-header">
  175 + <span class="px-staff-title">科技部老师业绩</span>
  176 + <el-button v-if="!dataForm.id" size="mini" type="success" icon="el-icon-plus" @click="addPxKjb(pxIndex)">添加科技部老师</el-button>
  177 + </div>
  178 + <div class="px-staff-list">
  179 + <div v-for="(kjb, kjbIndex) in px.lqHytkKjbsyjList" :key="kjbIndex" class="px-staff-row">
  180 + <div class="px-staff-item">
  181 + <div class="px-staff-fields">
  182 + <div class="px-staff-field">
  183 + <label>科技部老师</label>
  184 + <el-select v-model="kjb.kjbls" placeholder="选择科技部老师" clearable filterable size="mini" style="width: 200px;" @change="handleKjbChange(pxIndex, kjbIndex, kjb)">
  185 + <el-option v-for="(item, index) in kjbOptions" :key="index" :label="item.fullName" :value="item.id"></el-option>
  186 + </el-select>
  187 + </div>
  188 + <div class="px-staff-field">
  189 + <label>业绩</label>
  190 + <el-input v-model="kjb.kjblsyj" placeholder="请输入业绩" size="mini" style="width: 120px;" @input="formatPxStaffNumber(pxIndex, kjbIndex, 'kjblsyj', 'lqHytkKjbsyjList')">
  191 + <template slot="append">元</template>
  192 + </el-input>
  193 + </div>
  194 + <div class="px-staff-field">
  195 + <label>手工费</label>
  196 + <el-input v-model="kjb.laborCost" placeholder="手工费" size="mini" style="width: 120px;" @input="formatPxStaffNumber(pxIndex, kjbIndex, 'laborCost', 'lqHytkKjbsyjList')">
  197 + <template slot="append">元</template>
  198 + </el-input>
  199 + </div>
  200 + <div class="px-staff-field">
  201 + <label>次数</label>
  202 + <el-input-number v-model="kjb.hdpxNumber" :min="1" :max="999" placeholder="次数" size="mini" style="width: 120px;"></el-input-number>
  203 + </div>
  204 + <div class="px-staff-field" v-if="!dataForm.id">
  205 + <el-button size="mini" type="danger" icon="el-icon-delete" @click="removePxKjb(pxIndex, kjbIndex)">删除</el-button>
  206 + </div>
  207 + </div>
  208 + </div>
  209 + </div>
  210 + </div>
  211 + </div>
  212 +
  213 + <!-- 非科美品项提示 -->
  214 + <div class="px-staff-section" v-if="px.qt2 && px.qt2 !== '科美'">
  215 + <div class="px-staff-header">
  216 + <span class="px-staff-title">科技部老师业绩</span>
  217 + </div>
  218 + <div class="px-staff-tip">
  219 + <i class="el-icon-info"></i>
  220 + <span>当前品项类型为"{{ px.qt2 }}",无需配置科技部老师业绩</span>
  221 + </div>
  222 + </div>
145 </div> 223 </div>
  224 + </div>
  225 + </el-form-item>
  226 + </el-col>
  227 + <el-col :span="24">
  228 + <el-form-item label="备注" prop="bz">
  229 + <el-input v-model="dataForm.bz" placeholder="请输入" show-word-limit :style='{"width":"100%"}' type='textarea' :autosize='{"minRows":4,"maxRows":4}' >
  230 + </el-input>
  231 + </el-form-item>
  232 + </el-col>
  233 + <el-col :span="24">
  234 + <el-form-item label="上传文件" prop="fileUrl">
  235 + <NCC-UploadImg v-model="dataForm.fileUrl" :fileSize="30" sizeUnit="MB" :limit="9" >
  236 + </NCC-UploadImg>
146 </el-form-item> 237 </el-form-item>
147 </el-col> 238 </el-col>
148 </el-form> 239 </el-form>
@@ -157,6 +248,7 @@ @@ -157,6 +248,7 @@
157 import request from '@/utils/request' 248 import request from '@/utils/request'
158 import { getDictionaryDataSelector } from '@/api/systemData/dictionary' 249 import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
159 import { previewDataInterface } from '@/api/systemData/dataInterface' 250 import { previewDataInterface } from '@/api/systemData/dataInterface'
  251 + import { getInfo } from '@/api/user'
160 export default { 252 export default {
161 components: {}, 253 components: {},
162 props: [], 254 props: [],
@@ -169,37 +261,123 @@ @@ -169,37 +261,123 @@
169 id:'', 261 id:'',
170 id:undefined, 262 id:undefined,
171 md:undefined, 263 md:undefined,
172 - mcbh:undefined, 264 + mdbh:undefined,
173 mdmc:undefined, 265 mdmc:undefined,
174 hy:undefined, 266 hy:undefined,
175 - hyxm:undefined, 267 + hymc:undefined,
176 hyzh:undefined, 268 hyzh:undefined,
177 - jks:undefined,  
178 - jkszh:undefined,  
179 - jksxm:undefined, 269 + tkje:undefined,
  270 + sgfy:undefined,
180 bz:undefined, 271 bz:undefined,
181 tkpx:undefined, 272 tkpx:undefined,
182 tksj:undefined, 273 tksj:undefined,
183 tkr:undefined, 274 tkr:undefined,
  275 + fileUrl:undefined,
  276 + lqHytkJksyjList:[],
  277 + lqHytkKjbsyjList:[],
184 lqHytkMxList:[], 278 lqHytkMxList:[],
185 }, 279 },
186 rules: { 280 rules: {
  281 + md: [
  282 + { required: true, message: '请选择门店', trigger: 'change' }
  283 + ],
  284 + hy: [
  285 + { required: true, message: '请选择会员', trigger: 'change' }
  286 + ]
187 }, 287 },
188 mdOptions : [], 288 mdOptions : [],
189 hyOptions : [], 289 hyOptions : [],
190 pxOptions : [], 290 pxOptions : [],
  291 + jksOptions:[],
  292 + kjbOptions:[],
191 } 293 }
192 }, 294 },
193 computed: {}, 295 computed: {},
194 watch: {}, 296 watch: {},
195 created() { 297 created() {
196 - this.getmdOptions(); 298 + // 门店数据在loadStoreDataAndSetDefault中加载,避免重复
197 this.gethyOptions(); 299 this.gethyOptions();
198 this.getpxOptions(); 300 this.getpxOptions();
199 }, 301 },
200 mounted() { 302 mounted() {
201 }, 303 },
202 methods: { 304 methods: {
  305 + // 门店选择变化处理
  306 + handleMdChange(val) {
  307 + const selectedMd = this.mdOptions.find(item => item.id === val);
  308 + if (selectedMd) {
  309 + this.dataForm.mdbh = selectedMd.mdbh || selectedMd.id;
  310 + this.dataForm.mdmc = selectedMd.fullName;
  311 + console.log('选择门店:', selectedMd);
  312 + } else {
  313 + this.dataForm.mdbh = '';
  314 + this.dataForm.mdmc = '';
  315 + }
  316 + },
  317 + // 会员选择变化处理
  318 + handleHyChange(val) {
  319 + const selectedHy = this.hyOptions.find(item => item.id === val);
  320 + if (selectedHy) {
  321 + this.dataForm.hyzh = selectedHy.hyzh || selectedHy.id;
  322 + this.dataForm.hymc = selectedHy.fullName;
  323 + console.log('选择会员:', selectedHy);
  324 +
  325 + // 选择会员后,获取该会员的剩余品项
  326 + this.getpxOptions();
  327 + } else {
  328 + this.dataForm.hyzh = '';
  329 + this.dataForm.hymc = '';
  330 + this.pxOptions = []; // 清空品项选项
  331 + }
  332 + },
  333 + // 品项选择变化处理
  334 + handlePxChange(index, row) {
  335 + if (row.px) {
  336 + const selectedPx = this.pxOptions.find(item => item.id === row.px);
  337 + if (selectedPx) {
  338 + request({
  339 + url: `/api/Extend/LqXmzl/${selectedPx.id}`,
  340 + method: 'GET',
  341 + }).then((res) => {
  342 + let qt2 = res.data.qt2 || "";
  343 + let sgf = res.data.sgf || 0;
  344 + row.pxmc = selectedPx.fullName;
  345 + row.pxjg = selectedPx.ItemPrice || 0;
  346 + row.qt2 = qt2 || "";
  347 + row.yxf = selectedPx.ConsumedCount || 0; // 已消费
  348 + row.zgm = selectedPx.TotalPurchased || 1; // 总购买
  349 + row.ly = selectedPx.sourceType || "购买"; // 来源
  350 + row.projectNumber = 1; // 默认消费数量为1
  351 + row.sgf = sgf;
  352 +
  353 + // 如果品项类型不是"科美",清空科技部老师列表
  354 + if (row.qt2 !== '科美') {
  355 + row.lqHytkKjbsyjList = [];
  356 + }
  357 +
  358 + console.log('选择品项:', selectedPx.fullName, 'qt2:', selectedPx.qt2, '剩余数量:', selectedPx.RemainingCount);
  359 +
  360 + // 重新计算总金额和总手工费
  361 + this.calculateTotalAmount();
  362 + this.calculateTotalLaborCost();
  363 + })
  364 + }
  365 + } else {
  366 + // 清空品项时,重置所有相关字段
  367 + row.pxmc = '';
  368 + row.pxjg = 0;
  369 + row.qt2 = '';
  370 + row.yxf = 0;
  371 + row.zgm = 1;
  372 + row.ly = '购买';
  373 + row.projectNumber = 1;
  374 + row.lqHytkKjbsyjList = []; // 清空科技部老师列表
  375 +
  376 + // 重新计算总金额和总手工费
  377 + this.calculateTotalAmount();
  378 + this.calculateTotalLaborCost();
  379 + }
  380 + },
203 getmdOptions(){ 381 getmdOptions(){
204 previewDataInterface('730960205902251269').then(res => { 382 previewDataInterface('730960205902251269').then(res => {
205 this.mdOptions = res.data 383 this.mdOptions = res.data
@@ -210,11 +388,237 @@ @@ -210,11 +388,237 @@
210 this.hyOptions = res.data 388 this.hyOptions = res.data
211 }); 389 });
212 }, 390 },
213 - getpxOptions(){  
214 - previewDataInterface('730971133356016901').then(res => {  
215 - this.pxOptions = res.data 391 + // 获取品项选项(从会员剩余品项API获取)
  392 + async getpxOptions() {
  393 + if (!this.dataForm.hy) {
  394 + console.warn("请先选择会员");
  395 + this.pxOptions = [];
  396 + return;
  397 + }
  398 +
  399 + try {
  400 + const response = await request({
  401 + url: `/api/Extend/lqkhxx/GetMemberRemainingItems?memberId=${this.dataForm.hy}`,
  402 + method: 'GET',
  403 + });
  404 +
  405 + if (response.code == 200 && response.data && response.data.RemainingItems) {
  406 + this.pxOptions = response.data.RemainingItems.map(item => ({
  407 + fullName: item.ItemName,
  408 + id: item.ItemId,
  409 + value: item.ItemId,
  410 + label: item.ItemName,
  411 + px: item.ItemId,
  412 + pxmc: item.ItemName,
  413 + pxjg: item.ItemPrice || 0,
  414 + qt2: item.qt2 || "",
  415 + RemainingCount: item.RemainingCount || 0,
  416 + ItemPrice: item.ItemPrice || 0,
  417 + sgf: 0,
  418 + sourceType: item.SourceType || "购买",
  419 + TotalPurchased: item.TotalPurchased || 0,
  420 + ConsumedCount: item.ConsumedCount || 0
  421 + }));
  422 + console.log('获取会员剩余品项成功:', this.pxOptions);
  423 + } else {
  424 + console.warn("获取会员剩余品项失败,使用默认数据");
  425 + this.pxOptions = [];
  426 + }
  427 + } catch (error) {
  428 + console.error("获取会员剩余品项出错:", error);
  429 + this.pxOptions = [];
  430 + }
  431 + },
  432 + // 获取健康师选项
  433 + getjksOptions() {
  434 + request({
  435 + url: `/api/Extend/user?page=1&pageSize=1000&mdid=${this.dataForm.md}&gw=健康师`,
  436 + method: 'GET',
  437 + }).then((res) => {
  438 + if (res.code == 200 && res.data.list.length > 0) {
  439 + this.jksOptions = res.data.list.map(item => ({
  440 + fullName: item.realName || item.name || item.userName,
  441 + id: item.id,
  442 + value: item.id,
  443 + label: item.realName || item.name || item.userName,
  444 + jks: item.id,
  445 + jksxm: item.realName || item.name || item.userName,
  446 + jkszh: item.mobilePhone || item.account || item.userName
  447 + }));
  448 + } else {
  449 + this.jksOptions = [];
  450 + }
  451 + })
  452 + },
  453 + // 获取科技部老师选项
  454 + async getkjbOptions() {
  455 + await this.getKjbOptionsByOrganizeId();
  456 + },
  457 + // 根据门店ID获取科技部组织ID,再获取科技部老师列表
  458 + async getKjbOptionsByOrganizeId() {
  459 + try {
  460 + // 1. 先获取门店信息,获取科技部组织ID
  461 + const storeResponse = await request({
  462 + url: `/api/Extend/LqMdxx/${this.dataForm.md}`,
  463 + method: 'GET',
  464 + });
  465 +
  466 + let organizeId = "";
  467 + if (storeResponse.code == 200 && storeResponse.data) {
  468 + organizeId = storeResponse.data.kjb || "";
  469 + console.log('获取到科技部组织ID:', organizeId);
  470 + }
  471 +
  472 + if (!organizeId) {
  473 + console.warn('未获取到科技部组织ID');
  474 + this.kjbOptions = [];
  475 + return;
  476 + }
  477 +
  478 + // 2. 根据科技部组织ID获取科技部老师列表
  479 + const userResponse = await request({
  480 + url: `/api/Extend/user?page=1&pageSize=1000&organizeId=${organizeId}&gw=科技老师`,
  481 + method: 'GET',
  482 + });
  483 +
  484 + if (userResponse.code == 200 && userResponse.data && userResponse.data.list.length > 0) {
  485 + this.kjbOptions = userResponse.data.list.map(item => ({
  486 + fullName: item.realName || item.name || item.userName,
  487 + id: item.id,
  488 + value: item.id,
  489 + label: item.realName || item.name || item.userName,
  490 + kjbls: item.id,
  491 + kjblsxm: item.realName || item.name || item.userName,
  492 + kjblszh: item.mobilePhone || item.account || item.userName
  493 + }));
  494 + console.log('科技部老师列表:', this.kjbOptions);
  495 + } else {
  496 + console.warn('获取科技部老师列表失败');
  497 + this.kjbOptions = [];
  498 + }
  499 + } catch (error) {
  500 + console.error('获取科技部老师列表出错:', error);
  501 + this.kjbOptions = [];
  502 + }
  503 + },
  504 + // 品项健康师选择
  505 + handleJksChange(pxIndex, jksIndex, row) {
  506 + console.log('品项健康师选择:', row);
  507 + if (row.jks) {
  508 + // 根据选择的健康师ID获取用户信息
  509 + const selectedJks = this.jksOptions.find(item => item.id === row.jks);
  510 + if (selectedJks) {
  511 + // 填充姓名和账号
  512 + row.jksxm = selectedJks.fullName;
  513 + row.jkszh = selectedJks.userName || selectedJks.account || selectedJks.id;
  514 +
  515 + // 获取金三角信息
  516 + this.getJsjInfoByUserId(row.jks, (jsjId, jsjName) => {
  517 + row.jsjName = jsjName;
  518 + row.jsjId = jsjId;
  519 + });
  520 + }
  521 + } else {
  522 + // 清空相关字段
  523 + row.jksxm = '';
  524 + row.jkszh = '';
  525 + row.jsjId = '';
  526 + }
  527 + },
  528 + // 品项科技部老师选择
  529 + handleKjbChange(pxIndex, kjbIndex, row) {
  530 + console.log('品项科技部老师选择:', row);
  531 + if (row.kjbls) {
  532 + // 根据选择的科技部老师ID获取用户信息
  533 + const selectedKjb = this.kjbOptions.find(item => item.id === row.kjbls);
  534 + if (selectedKjb) {
  535 + // 填充姓名和账号
  536 + row.kjblsxm = selectedKjb.fullName;
  537 + row.kjblszh = selectedKjb.userName || selectedKjb.account || selectedKjb.id;
  538 + }
  539 + } else {
  540 + // 清空相关字段
  541 + row.kjblsxm = '';
  542 + row.kjblszh = '';
  543 + }
  544 + },
  545 + // 根据用户ID获取金三角信息
  546 + getJsjInfoByUserId(userId, callback) {
  547 + request({
  548 + url: `/api/Extend/lqycsdjsj/Actions/GetThisMonthJsjInfo?userId=${userId}`,
  549 + method: 'GET',
  550 + }).then((res) => {
  551 + if (res.code === 200 && res.data) {
  552 + // 假设返回的数据结构中有jsj_id字段
  553 + const jsjId = res.data.jsjId;
  554 + const jsjName = res.data.jsjName;
  555 +
  556 + if (callback) {
  557 + callback(jsjId, jsjName);
  558 + }
  559 + console.log('获取金三角信息成功:', res.data);
  560 + } else {
  561 + console.warn('获取金三角信息失败:', res.msg);
  562 + if (callback) {
  563 + callback('');
  564 + }
  565 + }
  566 + }).catch((err) => {
  567 + console.error('获取金三角信息出错:', err);
  568 + if (callback) {
  569 + callback('');
  570 + }
216 }); 571 });
217 }, 572 },
  573 + // 品项内人员业绩数字格式化
  574 + formatPxStaffNumber(pxIndex, staffIndex, field, listName) {
  575 + const targetList = this.dataForm.lqHytkMxList[pxIndex][listName];
  576 + if (targetList && targetList[staffIndex] && targetList[staffIndex][field] !== undefined) {
  577 + let value = targetList[staffIndex][field].toString().replace(/,/g, '');
  578 +
  579 + if (!/^\d*\.?\d*$/.test(value)) {
  580 + value = value.replace(/[^\d.]/g, '');
  581 + }
  582 +
  583 + targetList[staffIndex][field] = value;
  584 + }
  585 + },
  586 + // 获取品项剩余数量
  587 + getRemainingCount(px) {
  588 + if (px.px) {
  589 + const selectedPx = this.pxOptions.find(item => item.id === px.px);
  590 + if (selectedPx) {
  591 + return selectedPx.RemainingCount || 0;
  592 + }
  593 + }
  594 + return (px.zgm || 1) - (px.yxf || 0);
  595 + },
  596 + // 消费数量变化处理
  597 + onProjectNumberChange() {
  598 + // 重新计算总金额和总手工费
  599 + this.calculateTotalAmount();
  600 + this.calculateTotalLaborCost();
  601 + },
  602 + // 计算总退款金额
  603 + calculateTotalAmount() {
  604 + let totalAmount = 0;
  605 + this.dataForm.lqHytkMxList.forEach(px => {
  606 + if (px.px && px.pxjg && px.projectNumber) {
  607 + totalAmount += parseFloat(px.pxjg) * parseInt(px.projectNumber);
  608 + }
  609 + });
  610 + this.dataForm.tkje = totalAmount.toFixed(2);
  611 + },
  612 + // 计算总手工费
  613 + calculateTotalLaborCost() {
  614 + let totalLaborCost = 0;
  615 + this.dataForm.lqHytkMxList.forEach(px => {
  616 + if (px.sgf && px.projectNumber) {
  617 + totalLaborCost += parseFloat(px.sgf) * parseInt(px.projectNumber);
  618 + }
  619 + });
  620 + this.dataForm.sgfy = totalLaborCost.toFixed(2);
  621 + },
218 goBack() { 622 goBack() {
219 this.$emit('refresh') 623 this.$emit('refresh')
220 }, 624 },
@@ -230,13 +634,35 @@ @@ -230,13 +634,35 @@
230 method: 'get' 634 method: 'get'
231 }).then(res =>{ 635 }).then(res =>{
232 this.dataForm = res.data; 636 this.dataForm = res.data;
  637 + this.dataForm.fileUrl = this.dataForm.fileUrl?JSON.parse(this.dataForm.fileUrl):[];
233 }) 638 })
  639 + } else {
  640 + // 新建时自动设置当前用户门店
  641 + this.loadStoreDataAndSetDefault();
  642 + // 加载健康师和科技部老师选项
  643 + this.getjksOptions();
  644 + this.getkjbOptions();
  645 + // 初始化时计算总金额和总手工费
  646 + this.calculateTotalAmount();
  647 + this.calculateTotalLaborCost();
234 } 648 }
235 }) 649 })
236 }, 650 },
237 dataFormSubmit() { 651 dataFormSubmit() {
  652 +
238 this.$refs['elForm'].validate((valid) => { 653 this.$refs['elForm'].validate((valid) => {
239 if (valid) { 654 if (valid) {
  655 + // 验证品项数据
  656 + if (!this.validatePxList()) {
  657 + return;
  658 + }
  659 +
  660 + // 处理提交格式
  661 + this.processFormData();
  662 + console.log(this.dataForm)
  663 + // return
  664 +
  665 + this.dataForm.fileUrl = JSON.stringify(this.dataForm.fileUrl);
240 if (!this.dataForm.id) { 666 if (!this.dataForm.id) {
241 request({ 667 request({
242 url: `/api/Extend/LqHytkHytk`, 668 url: `/api/Extend/LqHytkHytk`,
@@ -273,22 +699,623 @@ @@ -273,22 +699,623 @@
273 } 699 }
274 }) 700 })
275 }, 701 },
276 - addHandleLqHytkMxEntityList() { 702 + // 品项相关方法
  703 + addHandleLqXhPxmxEntityList() {
277 let item = { 704 let item = {
278 - id:undefined,  
279 - gltkbh:undefined,  
280 - px:undefined,  
281 - mc:undefined,  
282 - tkje:undefined,  
283 - cs:undefined,  
284 - dchk:undefined,  
285 - fssj:undefined, 705 + id: undefined,
  706 + glkdbh: undefined,
  707 + px: undefined,
  708 + pxmc: undefined,
  709 + pxjg: undefined,
  710 + xfzs: undefined,
  711 + yxf: 0, // 已消费
  712 + zgm: 1, // 总购买
  713 + ly: '购买', // 来源
  714 + projectNumber: 1, // 消费数量
  715 + qt2: undefined, // 品项类型
  716 + lqHytkJksyjList: [], // 健康师业绩列表
  717 + lqHytkKjbsyjList: [], // 科技部老师业绩列表
286 } 718 }
287 - this.dataForm.lqHytkMxList.push(item) 719 + this.dataForm.lqHytkMxList.push(item);
  720 + // 重新计算总金额和总手工费
  721 + this.calculateTotalAmount();
  722 + this.calculateTotalLaborCost();
288 }, 723 },
289 - handleDelLqHytkMxEntityList(index) { 724 + handleDelLqXhPxmxEntityList(index) {
290 this.dataForm.lqHytkMxList.splice(index, 1); 725 this.dataForm.lqHytkMxList.splice(index, 1);
  726 + // 重新计算总金额和总手工费
  727 + this.calculateTotalAmount();
  728 + this.calculateTotalLaborCost();
  729 + },
  730 + validatePxList(){
  731 + const pxList = this.dataForm.lqHytkMxList;
  732 +
  733 + // 1. 验证是否有品项
  734 + if (!pxList || pxList.length === 0) {
  735 + this.$message.error('请至少添加一个品项');
  736 + return false;
  737 + }
  738 +
  739 + // 2. 验证每个品项的信息
  740 + for (let i = 0; i < pxList.length; i++) {
  741 + const px = pxList[i];
  742 +
  743 + // 验证品项基本信息
  744 + if (!px.px || !px.pxmc) {
  745 + this.$message.error(`第${i + 1}个品项信息不完整,请重新选择`);
  746 + return false;
  747 + }
  748 + if (!px.pxjg || parseFloat(px.pxjg) <= 0) {
  749 + this.$message.error(`第${i + 1}个品项的价格必须大于0`);
  750 + return false;
  751 + }
  752 +
  753 + // 验证退卡次数不能超过剩余次数
  754 + if (px.RemainingCount && px.projectNumber > px.RemainingCount) {
  755 + this.$message.error(`第${i + 1}个品项的退卡次数(${px.projectNumber})不能超过剩余次数(${px.RemainingCount})`);
  756 + return false;
  757 + }
  758 +
  759 + // 验证健康师
  760 + if (!px.lqHytkJksyjList || px.lqHytkJksyjList.length === 0) {
  761 + this.$message.error(`第${i + 1}个品项必须至少选择一个健康师`);
  762 + return false;
  763 + }
  764 +
  765 + // 计算健康师业绩总和
  766 + let jksTotalYj = 0;
  767 + let jksTotalLaborCost = 0;
  768 + let jksTotalNumber = 0;
  769 +
  770 + for (let j = 0; j < px.lqHytkJksyjList.length; j++) {
  771 + const jks = px.lqHytkJksyjList[j];
  772 +
  773 + // 验证健康师是否选择
  774 + if (!jks.jks || !jks.jksxm) {
  775 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师必须选择`);
  776 + return false;
  777 + }
  778 +
  779 + // 验证健康师业绩必须填写
  780 + if (!jks.jksyj || jks.jksyj.trim() === "") {
  781 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师业绩必须填写`);
  782 + return false;
  783 + }
  784 +
  785 + // 验证业绩为数字
  786 + const yj = parseFloat(jks.jksyj);
  787 + if (isNaN(yj) || yj < 0) {
  788 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师业绩必须为有效数字`);
  789 + return false;
  790 + }
  791 +
  792 + jksTotalYj += yj;
  793 + jksTotalLaborCost += parseFloat(jks.laborCost) || 0;
  794 + jksTotalNumber += parseInt(jks.kdpxNumber) || 0;
  795 + }
  796 +
  797 + // 验证健康师业绩总和等于品项金额
  798 + const pxTotalAmount = px.pxjg * px.projectNumber;
  799 + if (Math.abs(jksTotalYj - pxTotalAmount) > 0.01) {
  800 + this.$message.error(`第${i + 1}个品项的健康师业绩总和(${jksTotalYj.toFixed(2)})必须等于品项金额(${pxTotalAmount.toFixed(2)})`);
  801 + return false;
  802 + }
  803 +
  804 + // 验证健康师手工费总和等于品项手工费
  805 + const pxTotalLaborCost = (px.sgf || 0) * px.projectNumber;
  806 + if (Math.abs(jksTotalLaborCost - pxTotalLaborCost) > 0.01) {
  807 + this.$message.error(`第${i + 1}个品项的健康师手工费总和(${jksTotalLaborCost.toFixed(2)})必须等于品项手工费(${pxTotalLaborCost.toFixed(2)})`);
  808 + return false;
  809 + }
  810 +
  811 + // 验证健康师次数总和等于品项次数
  812 + if (jksTotalNumber !== px.projectNumber) {
  813 + this.$message.error(`第${i + 1}个品项的健康师次数总和(${jksTotalNumber})必须等于品项次数(${px.projectNumber})`);
  814 + return false;
  815 + }
  816 +
  817 + // 如果是科美品项,验证科技部老师
  818 + if (px.qt2 === '科美') {
  819 + if (!px.lqHytkKjbsyjList || px.lqHytkKjbsyjList.length === 0) {
  820 + this.$message.error(`第${i + 1}个品项是科美品项,必须至少选择一个科技部老师`);
  821 + return false;
  822 + }
  823 +
  824 + // 计算科技部老师业绩总和
  825 + let kjbTotalYj = 0;
  826 + let kjbTotalLaborCost = 0;
  827 + let kjbTotalNumber = 0;
  828 +
  829 + for (let k = 0; k < px.lqHytkKjbsyjList.length; k++) {
  830 + const kjb = px.lqHytkKjbsyjList[k];
  831 +
  832 + // 验证科技部老师是否选择
  833 + if (!kjb.kjbls || !kjb.kjblsxm) {
  834 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师必须选择`);
  835 + return false;
  836 + }
  837 +
  838 + // 验证科技部老师业绩必须填写
  839 + if (!kjb.kjblsyj || kjb.kjblsyj.trim() === "") {
  840 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师业绩必须填写`);
  841 + return false;
  842 + }
  843 +
  844 + // 验证业绩为数字
  845 + const yj = parseFloat(kjb.kjblsyj);
  846 + if (isNaN(yj) || yj < 0) {
  847 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师业绩必须为有效数字`);
  848 + return false;
  849 + }
  850 +
  851 + kjbTotalYj += yj;
  852 + kjbTotalLaborCost += parseFloat(kjb.laborCost) || 0;
  853 + kjbTotalNumber += parseInt(kjb.hdpxNumber) || 0;
  854 + }
  855 +
  856 + // 验证科技部老师业绩总和等于品项金额
  857 + if (Math.abs(kjbTotalYj - pxTotalAmount) > 0.01) {
  858 + this.$message.error(`第${i + 1}个品项的科技部老师业绩总和(${kjbTotalYj.toFixed(2)})必须等于品项金额(${pxTotalAmount.toFixed(2)})`);
  859 + return false;
  860 + }
  861 +
  862 + // 验证科技部老师手工费总和等于品项手工费
  863 + if (Math.abs(kjbTotalLaborCost - pxTotalLaborCost) > 0.01) {
  864 + this.$message.error(`第${i + 1}个品项的科技部老师手工费总和(${kjbTotalLaborCost.toFixed(2)})必须等于品项手工费(${pxTotalLaborCost.toFixed(2)})`);
  865 + return false;
  866 + }
  867 +
  868 + // 验证科技部老师次数总和等于品项次数
  869 + if (kjbTotalNumber !== px.projectNumber) {
  870 + this.$message.error(`第${i + 1}个品项的科技部老师次数总和(${kjbTotalNumber})必须等于品项次数(${px.projectNumber})`);
  871 + return false;
  872 + }
  873 + }
  874 + }
  875 +
  876 + return true;
  877 + },
  878 + // 处理表单数据
  879 + processFormData() {
  880 + // 检查是否有科美品项
  881 + const hasKemei = this.dataForm.lqHytkMxList.some(px => px.qt2 === '科美');
  882 +
  883 + // 设置是否有科技部
  884 + this.dataForm.sfykjb = hasKemei ? "是" : "否";
  885 +
  886 + // 处理品项列表,转换为指定格式
  887 + this.dataForm.lqHytkMxList = this.dataForm.lqHytkMxList.map(px => {
  888 + // 计算退卡金额和总价
  889 + const tkje = parseFloat(px.pxjg) * parseInt(px.projectNumber) || 0;
  890 + const f_TotalPrice = tkje;
  891 +
  892 + // 处理健康师列表
  893 + const lqHytkJksyjList = (px.lqHytkJksyjList || []).map(jks => ({
  894 + jks: jks.jks || '',
  895 + jksxm: jks.jksxm || '',
  896 + jkszh: jks.jkszh || '',
  897 + jksyj: parseFloat(jks.jksyj) || 0,
  898 + f_jsjid: jks.jsjId || '',
  899 + f_tkpxid: px.px || '',
  900 + f_LaborCost: parseFloat(jks.laborCost) || 0,
  901 + f_tkpxNumber: parseInt(px.projectNumber) || 0
  902 + }));
  903 +
  904 + // 处理科技部老师列表
  905 + const lqHytkKjbsyjList = (px.lqHytkKjbsyjList || []).map(kjb => ({
  906 + kjbls: kjb.kjbls || '',
  907 + kjblsxm: kjb.kjblsxm || '',
  908 + kjblszh: kjb.kjblszh || '',
  909 + kjblsyj: parseFloat(kjb.kjblsyj) || 0,
  910 + f_tkpxid: px.px || '',
  911 + f_LaborCost: parseFloat(kjb.laborCost) || 0,
  912 + f_tkpxNumber: parseInt(px.projectNumber) || 0
  913 + }));
  914 +
  915 + return {
  916 + px: px.px || '',
  917 + pxmc: px.pxmc || '',
  918 + pxjg: parseFloat(px.pxjg) || 0,
  919 + tkje: tkje,
  920 + f_ProjectNumber: parseInt(px.projectNumber) || 0,
  921 + f_SourceType: px.qt2 || '',
  922 + f_TotalPrice: f_TotalPrice,
  923 + lqHytkJksyjList: lqHytkJksyjList,
  924 + lqHytkKjbsyjList: lqHytkKjbsyjList
  925 + };
  926 + });
  927 + },
  928 + // 品项健康师相关方法
  929 + addPxJks(pxIndex) {
  930 + if (!this.dataForm.lqHytkMxList[pxIndex].lqHytkJksyjList) {
  931 + this.$set(this.dataForm.lqHytkMxList[pxIndex], 'lqHytkJksyjList', []);
  932 + }
  933 + let item = {
  934 + "jks": "",
  935 + "jksxm": "",
  936 + "jkszh": "",
  937 + "jksyj": "",
  938 + "jsjId": "",
  939 + "laborCost": 1,
  940 + "kdpxNumber": 0
  941 + }
  942 + this.dataForm.lqHytkMxList[pxIndex].lqHytkJksyjList.push(item);
  943 + },
  944 + removePxJks(pxIndex, jksIndex) {
  945 + this.dataForm.lqHytkMxList[pxIndex].lqHytkJksyjList.splice(jksIndex, 1);
  946 + },
  947 + // 品项科技部老师相关方法
  948 + addPxKjb(pxIndex) {
  949 + if (!this.dataForm.lqHytkMxList[pxIndex].lqHytkKjbsyjList) {
  950 + this.$set(this.dataForm.lqHytkMxList[pxIndex], 'lqHytkKjbsyjList', []);
  951 + }
  952 + let item = {
  953 + "kjbls": "",
  954 + "kjblsyj": "",
  955 + "kjblsxm": "",
  956 + "kjblszh": "",
  957 + "laborCost": 0,
  958 + "hdpxNumber": 0
  959 + }
  960 + this.dataForm.lqHytkMxList[pxIndex].lqHytkKjbsyjList.push(item);
  961 + },
  962 + removePxKjb(pxIndex, kjbIndex) {
  963 + this.dataForm.lqHytkMxList[pxIndex].lqHytkKjbsyjList.splice(kjbIndex, 1);
  964 + },
  965 + // 加载门店数据并设置默认门店
  966 + loadStoreDataAndSetDefault() {
  967 + console.log('开始加载门店数据和用户信息...');
  968 + // 先加载门店数据
  969 + this.loadStoreDataPromise().then(() => {
  970 + // 门店数据加载完成后,获取用户信息
  971 + return this.getCurrentUserStorePromise();
  972 + }).then((userData) => {
  973 + if (userData && userData.mdid) {
  974 + const userStoreId = userData.mdid;
  975 + console.log('用户门店ID:', userStoreId);
  976 + console.log('门店选项列表:', this.mdOptions);
  977 +
  978 + // 检查用户门店ID是否在门店列表中
  979 + const matchingStore = this.mdOptions.find(store => store.id === userStoreId);
  980 + if (matchingStore) {
  981 + this.dataForm.md = userStoreId;
  982 + this.dataForm.mdmc = matchingStore.fullName;
  983 + this.dataForm.mdbh = matchingStore.id;
  984 + console.log('找到匹配的门店,设置默认门店ID:', userStoreId);
  985 + console.log('匹配的门店信息:', matchingStore);
  986 + } else {
  987 + console.warn('用户门店ID在门店列表中未找到匹配项');
  988 + console.log('用户门店ID:', userStoreId);
  989 + console.log('可用门店ID列表:', this.mdOptions.map(s => s.id));
  990 + }
  991 + } else {
  992 + console.warn('用户数据中没有门店ID,无法设置默认值');
  993 + }
  994 +
  995 + // 加载健康师和科技部老师选项
  996 + this.getjksOptions();
  997 + this.getkjbOptions();
  998 + }).catch(err => {
  999 + console.error('加载数据失败:', err);
  1000 + });
  1001 + },
  1002 + // 加载门店数据
  1003 + loadStoreDataPromise() {
  1004 + // 使用原来的数据接口方式
  1005 + return previewDataInterface('730960205902251269').then(res => {
  1006 + console.log('门店API原始响应:', res);
  1007 + if (res.data && res.data.length > 0) {
  1008 + this.mdOptions = res.data;
  1009 + console.log('门店数据加载成功:', this.mdOptions);
  1010 + return res.data;
  1011 + } else {
  1012 + console.warn('门店数据为空');
  1013 + return [];
  1014 + }
  1015 + }).catch(err => {
  1016 + console.error('门店数据加载失败:', err);
  1017 + return [];
  1018 + });
  1019 + },
  1020 + // 获取当前用户门店信息
  1021 + getCurrentUserStorePromise() {
  1022 + return new Promise((resolve, reject) => {
  1023 + getInfo().then(res => {
  1024 + resolve(res.data.userInfo);
  1025 + }).catch(err => {
  1026 + console.error('获取当前用户信息失败:', err);
  1027 + reject(err);
  1028 + });
  1029 + });
291 }, 1030 },
292 } 1031 }
293 } 1032 }
294 </script> 1033 </script>
  1034 +
  1035 +<style scoped>
  1036 +/* 表单布局优化 */
  1037 +.form-layout {
  1038 + margin: 0;
  1039 +}
  1040 +
  1041 +.form-layout .el-col {
  1042 + margin-bottom: 18px;
  1043 +}
  1044 +
  1045 +/* 表单行间距优化 */
  1046 +.form-layout .el-form-item {
  1047 + margin-bottom: 0;
  1048 +}
  1049 +
  1050 +/* 表单项高度统一 */
  1051 +.form-layout .el-form-item__content {
  1052 + line-height: 32px;
  1053 +}
  1054 +
  1055 +/* 表单项标签样式 */
  1056 +.form-layout .el-form-item__label {
  1057 + line-height: 32px;
  1058 + padding-right: 12px;
  1059 + font-weight: 500;
  1060 +}
  1061 +
  1062 +/* 输入框高度统一 */
  1063 +.form-layout .el-input__inner,
  1064 +.form-layout .el-select .el-input__inner {
  1065 + height: 32px;
  1066 + line-height: 32px;
  1067 +}
  1068 +
  1069 +/* 单选框组样式 */
  1070 +.form-layout .el-radio-group {
  1071 + line-height: 32px;
  1072 +}
  1073 +
  1074 +.form-layout .el-radio {
  1075 + margin-right: 20px;
  1076 + line-height: 32px;
  1077 +}
  1078 +
  1079 +/* 表格标题样式 */
  1080 +.table-header {
  1081 + display: flex;
  1082 + justify-content: space-between;
  1083 + align-items: center;
  1084 + margin-bottom: 12px;
  1085 + padding: 12px 16px;
  1086 + background: #f5f7fa;
  1087 + border-radius: 6px;
  1088 + border-left: 4px solid #409EFF;
  1089 + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  1090 +}
  1091 +
  1092 +.table-title {
  1093 + font-size: 15px;
  1094 + font-weight: 600;
  1095 + color: #303133;
  1096 +}
  1097 +
  1098 +/* 品项列表容器 */
  1099 +.px-list-container {
  1100 + width: 100%;
  1101 + margin-top: 8px;
  1102 +}
  1103 +
  1104 +/* 品项项 */
  1105 +.px-item {
  1106 + margin-bottom: 24px;
  1107 + border: 1px solid #e4e7ed;
  1108 + border-radius: 8px;
  1109 + background: #fff;
  1110 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  1111 + overflow: hidden;
  1112 + transition: all 0.3s ease;
  1113 +}
  1114 +
  1115 +.px-item:hover {
  1116 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  1117 +}
  1118 +
  1119 +/* 品项基本信息 */
  1120 +.px-basic-info {
  1121 + background: #f8f9fa;
  1122 + padding: 20px;
  1123 + border-bottom: 1px solid #e4e7ed;
  1124 +}
  1125 +
  1126 +.px-item-header {
  1127 + display: flex;
  1128 + justify-content: space-between;
  1129 + align-items: center;
  1130 + margin-bottom: 18px;
  1131 +}
  1132 +
  1133 +.px-item-title {
  1134 + font-size: 16px;
  1135 + font-weight: 600;
  1136 + color: #303133;
  1137 +}
  1138 +
  1139 +/* 品项选择行 */
  1140 +.px-select-row {
  1141 + margin-bottom: 15px;
  1142 +}
  1143 +
  1144 +/* 品项详细信息 */
  1145 +.px-detail-info {
  1146 + background: #fff;
  1147 + padding: 15px;
  1148 + border-radius: 6px;
  1149 + border: 1px solid #e4e7ed;
  1150 + margin-bottom: 15px;
  1151 +}
  1152 +
  1153 +.px-detail-row {
  1154 + display: flex;
  1155 + flex-wrap: wrap;
  1156 + gap: 20px;
  1157 + margin-bottom: 15px;
  1158 +}
  1159 +
  1160 +.px-detail-item {
  1161 + display: flex;
  1162 + align-items: center;
  1163 +}
  1164 +
  1165 +.px-detail-label {
  1166 + font-size: 14px;
  1167 + color: #606266;
  1168 + font-weight: 500;
  1169 + margin-right: 8px;
  1170 +}
  1171 +
  1172 +.px-detail-value {
  1173 + font-size: 14px;
  1174 + color: #303133;
  1175 + font-weight: 600;
  1176 +}
  1177 +
  1178 +/* 消费数量输入行 */
  1179 +.px-consumption-row {
  1180 + display: flex;
  1181 + align-items: center;
  1182 + gap: 10px;
  1183 +}
  1184 +
  1185 +/* 人员业绩区域 */
  1186 +.px-staff-section {
  1187 + padding: 18px 20px;
  1188 + border-bottom: 1px solid #e4e7ed;
  1189 +}
  1190 +
  1191 +.px-staff-section:last-child {
  1192 + border-bottom: none;
  1193 +}
  1194 +
  1195 +.px-staff-header {
  1196 + display: flex;
  1197 + justify-content: space-between;
  1198 + align-items: center;
  1199 + margin-bottom: 12px;
  1200 +}
  1201 +
  1202 +.px-staff-title {
  1203 + font-size: 14px;
  1204 + font-weight: 600;
  1205 + color: #409EFF;
  1206 +}
  1207 +
  1208 +.px-staff-list {
  1209 + display: flex;
  1210 + flex-direction: column;
  1211 + gap: 10px;
  1212 +}
  1213 +
  1214 +.px-staff-row {
  1215 + width: 100%;
  1216 +}
  1217 +
  1218 +.px-staff-item {
  1219 + display: flex;
  1220 + flex-direction: column;
  1221 + padding: 12px 16px;
  1222 + border: 1px solid #e4e7ed;
  1223 + border-radius: 6px;
  1224 + background: #fafafa;
  1225 + transition: all 0.2s ease;
  1226 +}
  1227 +
  1228 +.px-staff-item:hover {
  1229 + background: #f5f7fa;
  1230 + border-color: #c0c4cc;
  1231 +}
  1232 +
  1233 +.px-staff-info {
  1234 + display: flex;
  1235 + justify-content: space-between;
  1236 + align-items: center;
  1237 + margin-bottom: 10px;
  1238 +}
  1239 +
  1240 +.px-staff-name {
  1241 + font-size: 14px;
  1242 + font-weight: 600;
  1243 + color: #303133;
  1244 +}
  1245 +
  1246 +.px-staff-fields {
  1247 + display: flex;
  1248 + flex-wrap: wrap;
  1249 + gap: 15px;
  1250 + align-items: flex-end;
  1251 +}
  1252 +
  1253 +.px-staff-field {
  1254 + display: flex;
  1255 + flex-direction: column;
  1256 + gap: 4px;
  1257 +}
  1258 +
  1259 +.px-staff-field label {
  1260 + font-size: 12px;
  1261 + color: #606266;
  1262 + font-weight: 500;
  1263 + white-space: nowrap;
  1264 +}
  1265 +
  1266 +/* 科技部老师提示信息 */
  1267 +.px-staff-tip {
  1268 + display: flex;
  1269 + align-items: center;
  1270 + padding: 12px 16px;
  1271 + background: #f0f9ff;
  1272 + border: 1px solid #b3d8ff;
  1273 + border-radius: 6px;
  1274 + color: #409eff;
  1275 + font-size: 14px;
  1276 +}
  1277 +
  1278 +.px-staff-tip i {
  1279 + margin-right: 8px;
  1280 + font-size: 16px;
  1281 +}
  1282 +
  1283 +/* 输入框组样式 */
  1284 +.el-input-group__append {
  1285 + background: #f5f7fa;
  1286 + border-color: #dcdfe6;
  1287 + color: #606266;
  1288 +}
  1289 +
  1290 +/* 响应式布局 */
  1291 +@media (max-width: 1200px) {
  1292 + .form-layout .el-col[class*="el-col-8"] {
  1293 + width: 50%;
  1294 + margin-bottom: 16px;
  1295 + }
  1296 +}
  1297 +
  1298 +@media (max-width: 768px) {
  1299 + .form-layout .el-col {
  1300 + margin-bottom: 12px;
  1301 + }
  1302 +
  1303 + .form-layout .el-col[class*="el-col-8"] {
  1304 + width: 100%;
  1305 + padding-left: 0;
  1306 + padding-right: 0;
  1307 + margin-bottom: 16px;
  1308 + }
  1309 +
  1310 + .px-basic-fields {
  1311 + flex-direction: column;
  1312 + align-items: stretch;
  1313 + gap: 16px;
  1314 + }
  1315 +
  1316 + .px-field {
  1317 + width: 100%;
  1318 + min-width: auto;
  1319 + }
  1320 +}
  1321 +</style>
antis-ncc-admin/src/views/lqKdKdjlb/Form.vue
@@ -498,6 +498,50 @@ export default { @@ -498,6 +498,50 @@ export default {
498 this.$message.error(`第${i + 1}个品项请至少添加一个健康师业绩`); 498 this.$message.error(`第${i + 1}个品项请至少添加一个健康师业绩`);
499 return false; 499 return false;
500 } 500 }
  501 +
  502 + // 验证每个健康师是否选择
  503 + for (let j = 0; j < px.lqKdJksyjList.length; j++) {
  504 + const jks = px.lqKdJksyjList[j];
  505 + if (!jks.jks || !jks.jksxm) {
  506 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师必须选择`);
  507 + return false;
  508 + }
  509 + if (!jks.jksyj || jks.jksyj.trim() === "") {
  510 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师业绩必须填写`);
  511 + return false;
  512 + }
  513 + const yj = parseFloat(jks.jksyj);
  514 + if (isNaN(yj) || yj < 0) {
  515 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师业绩必须为有效数字`);
  516 + return false;
  517 + }
  518 + }
  519 +
  520 + // 如果是科美品项,验证科技部老师
  521 + if (px.qt2 === '科美') {
  522 + if (!px.lqKdKjbsyjList || px.lqKdKjbsyjList.length === 0) {
  523 + this.$message.error(`第${i + 1}个品项是科美品项,必须至少选择一个科技部老师`);
  524 + return false;
  525 + }
  526 +
  527 + // 验证每个科技部老师是否选择
  528 + for (let k = 0; k < px.lqKdKjbsyjList.length; k++) {
  529 + const kjb = px.lqKdKjbsyjList[k];
  530 + if (!kjb.kjbls || !kjb.kjblsxm) {
  531 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师必须选择`);
  532 + return false;
  533 + }
  534 + if (!kjb.kjblsyj || kjb.kjblsyj.trim() === "") {
  535 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师业绩必须填写`);
  536 + return false;
  537 + }
  538 + const yj = parseFloat(kjb.kjblsyj);
  539 + if (isNaN(yj) || yj < 0) {
  540 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师业绩必须为有效数字`);
  541 + return false;
  542 + }
  543 + }
  544 + }
501 } 545 }
502 546
503 // 3. 验证每个品项金额等于该品项健康师业绩之和 547 // 3. 验证每个品项金额等于该品项健康师业绩之和
@@ -697,7 +741,7 @@ export default { @@ -697,7 +741,7 @@ export default {
697 this.$nextTick(() => { 741 this.$nextTick(() => {
698 this.initPxQt2Fields(); 742 this.initPxQt2Fields();
699 }); 743 });
700 - this.dataForm.f_FileUrl = JSON.parse(this.dataForm.f_FileUrl); 744 + this.dataForm.f_FileUrl = this.dataForm.F_FIleUrl?JSON.parse(this.dataForm.F_FIleUrl):[];
701 }) 745 })
702 } else { 746 } else {
703 // 新增时先加载门店数据,再获取用户门店 747 // 新增时先加载门店数据,再获取用户门店
antis-ncc-admin/src/views/lqXhHyhk/Form.vue
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 </el-input> 9 </el-input>
10 </el-form-item> 10 </el-form-item>
11 </el-col> 11 </el-col>
12 - <el-col :span="8"> 12 + <el-col :span="6">
13 <el-form-item label="门店" prop="md" required> 13 <el-form-item label="门店" prop="md" required>
14 <el-select v-model="dataForm.md" placeholder="请选择" clearable :style='{"width":"100%"}' filterable @change="handleMdChange"> 14 <el-select v-model="dataForm.md" placeholder="请选择" clearable :style='{"width":"100%"}' filterable @change="handleMdChange">
15 <el-option v-for="(item, index) in mdOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> 15 <el-option v-for="(item, index) in mdOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option>
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 </el-col> 30 </el-col>
31 31
32 <!-- 会员信息 --> 32 <!-- 会员信息 -->
33 - <el-col :span="8"> 33 + <el-col :span="6">
34 <el-form-item label="会员" prop="hy" required> 34 <el-form-item label="会员" prop="hy" required>
35 <el-select v-model="dataForm.hy" placeholder="请选择" clearable :style='{"width":"100%"}' filterable @change="handleHyChange"> 35 <el-select v-model="dataForm.hy" placeholder="请选择" clearable :style='{"width":"100%"}' filterable @change="handleHyChange">
36 <el-option v-for="(item, index) in hyOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> 36 <el-option v-for="(item, index) in hyOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option>
@@ -57,14 +57,14 @@ @@ -57,14 +57,14 @@
57 </el-col> 57 </el-col>
58 58
59 <!-- 费用信息 --> 59 <!-- 费用信息 -->
60 - <el-col :span="8"> 60 + <el-col :span="6">
61 <el-form-item label="消费金额" prop="xfje" required> 61 <el-form-item label="消费金额" prop="xfje" required>
62 <el-input v-model="dataForm.xfje" placeholder="自动计算" clearable readonly :style='{"width":"100%"}'> 62 <el-input v-model="dataForm.xfje" placeholder="自动计算" clearable readonly :style='{"width":"100%"}'>
63 <template slot="append">元</template> 63 <template slot="append">元</template>
64 </el-input> 64 </el-input>
65 </el-form-item> 65 </el-form-item>
66 </el-col> 66 </el-col>
67 - <el-col :span="8"> 67 + <el-col :span="6">
68 <el-form-item label="手工费用" prop="sgfy"> 68 <el-form-item label="手工费用" prop="sgfy">
69 <el-input v-model="dataForm.sgfy" placeholder="自动计算" clearable readonly :style='{"width":"100%"}'> 69 <el-input v-model="dataForm.sgfy" placeholder="自动计算" clearable readonly :style='{"width":"100%"}'>
70 <template slot="append">元</template> 70 <template slot="append">元</template>
@@ -941,6 +941,12 @@ @@ -941,6 +941,12 @@
941 for (let j = 0; j < px.lqXhJksyjList.length; j++) { 941 for (let j = 0; j < px.lqXhJksyjList.length; j++) {
942 const jks = px.lqXhJksyjList[j]; 942 const jks = px.lqXhJksyjList[j];
943 943
  944 + // 验证健康师是否选择
  945 + if (!jks.jks || !jks.jksxm) {
  946 + this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师必须选择`);
  947 + return false;
  948 + }
  949 +
944 // 验证健康师业绩必须填写 950 // 验证健康师业绩必须填写
945 if (!jks.jksyj || jks.jksyj.trim() === "") { 951 if (!jks.jksyj || jks.jksyj.trim() === "") {
946 this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师业绩必须填写`); 952 this.$message.error(`第${i + 1}个品项的第${j + 1}个健康师业绩必须填写`);
@@ -994,6 +1000,12 @@ @@ -994,6 +1000,12 @@
994 for (let k = 0; k < px.lqXhKjbsyjList.length; k++) { 1000 for (let k = 0; k < px.lqXhKjbsyjList.length; k++) {
995 const kjb = px.lqXhKjbsyjList[k]; 1001 const kjb = px.lqXhKjbsyjList[k];
996 1002
  1003 + // 验证科技部老师是否选择
  1004 + if (!kjb.kjbls || !kjb.kjblsxm) {
  1005 + this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师必须选择`);
  1006 + return false;
  1007 + }
  1008 +
997 // 验证科技部老师业绩必须填写 1009 // 验证科技部老师业绩必须填写
998 if (!kjb.kjblsyj || kjb.kjblsyj.trim() === "") { 1010 if (!kjb.kjblsyj || kjb.kjblsyj.trim() === "") {
999 this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师业绩必须填写`); 1011 this.$message.error(`第${i + 1}个品项的第${k + 1}个科技部老师业绩必须填写`);
antis-ncc-admin/src/views/lqXhHyhk/index.vue
@@ -126,7 +126,7 @@ @@ -126,7 +126,7 @@
126 <el-table-column prop="czry" label="操作人员" align="left" /> 126 <el-table-column prop="czry" label="操作人员" align="left" />
127 <el-table-column label="操作" fixed="right" width="100"> 127 <el-table-column label="操作" fixed="right" width="100">
128 <template slot-scope="scope"> 128 <template slot-scope="scope">
129 - <el-button type="text" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button> 129 + <el-button type="text" @click="addOrUpdateHandle(scope.row.id)" >查看</el-button>
130 <el-button type="text" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button> 130 <el-button type="text" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button>
131 </template> 131 </template>
132 </el-table-column> 132 </el-table-column>