Explorar o código

1、更新软床报价代码

MY hai 2 días
pai
achega
3784cba98f

+ 26 - 0
JLHHJSvr/Com/GetSoftBedConfigureList.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using JLHHJSvr.Com.Model;
+using LJLib.Net.SPI.Com;
+
+namespace JLHHJSvr.Com
+{
+    public sealed class GetSoftBedConfigureListRequest : ILJRequest<GetSoftBedConfigureListResponse>
+    {
+        public override string GetApiName()
+        {
+            return "GetSoftBedConfigureList";
+        }
+        /// <summary>
+        /// 登录token
+        /// </summary>
+        public string token { get; set; }
+        public u_softbed softbed { get; set; }
+    }
+
+    public sealed class GetSoftBedConfigureListResponse : LJResponse
+    {
+    }
+}

+ 3 - 3
JLHHJSvr/Com/Model/CalCulationFormula.cs

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
 
 namespace JLHHJSvr.Com.Model
 {
-    public sealed class CalCulationFormula
+    public sealed class FormulaItem
     {
         /// <summary>
         /// 公式id
@@ -36,9 +36,9 @@ namespace JLHHJSvr.Com.Model
                 return true;
             }
             //内存地址不相等,就得比属性
-            if (o is CalCulationFormula)
+            if (o is FormulaItem)
             {
-                CalCulationFormula item = (CalCulationFormula)o;
+                FormulaItem item = (FormulaItem)o;
                 return formula_id == item.formula_id &&
                 formula_name.Equals(item.formula_name);
             }

+ 4 - 1
JLHHJSvr/Com/Model/u_configure_code.cs

@@ -66,6 +66,9 @@ namespace JLHHJSvr.Com.Model
         public string priceratestr { get; set; }
         public byte? ifpack { get; set; }
         public string zj_special { get; set; }
-
+        /// <summary>
+        /// 部件选配项值
+        /// </summary>
+        public List<u_configure_codemx> codeMxList { get; set; }
     }
 }

+ 2 - 0
JLHHJSvr/Com/Model/u_softbed.cs

@@ -32,6 +32,7 @@ namespace JLHHJSvr.Com.Model
         public decimal taxrate { get; set; }
         public decimal other_rate { get; set; }
         public decimal extras_cost { get; set; }
+        public byte money_type { get; set; }
         public decimal moneyrate { get; set; }
         public string dscrp { get; set; }
         public decimal costamt { get; set; }
@@ -39,6 +40,7 @@ namespace JLHHJSvr.Com.Model
         public decimal nottax_dept_cost { get; set; }
         public decimal dept_cost { get; set; }
         public decimal foreign_cost { get; set; }
+        public decimal dept_profitrate { get; set; }
         public DateTime? audit_date { get; set; }
         public string audit_emp { get; set; }
         public DateTime? update_date { get; set; }

+ 4 - 0
JLHHJSvr/DataStore/web_softbed_choose.xml

@@ -21,6 +21,7 @@ SELECT u_softbed.softbed_id
 	,u_softbed.taxes
 	,u_softbed.other_rate
 	,u_softbed.extras_cost
+	,u_softbed.money_type
 	,u_softbed.moneyrate
 	,u_softbed.dscrp
 	,u_softbed.costamt
@@ -39,6 +40,9 @@ FROM u_softbed
 	<when>
 		u_softbed.is_template = 1
 	</when>
+	<when notnull="@arg_template_id">
+		u_softbed.softbed_id = @arg_template_id
+	</when>
 	<when notnull="@arg_search">
 		u_softbed.softbed_code LIKE '%' + @arg_search + '%' OR u_softbed.softbed_name LIKE '%' + @arg_search + '%' OR u_softbed.softbed_relcode LIKE '%' + @arg_search + '%'
 	</when>

+ 50 - 0
JLHHJSvr/Excutor/GetSoftBedConfigureListExcutor.cs

@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Data.SqlClient;
+using System.Linq;
+using DirectService.Tools;
+using JLHHJSvr.BLL;
+using JLHHJSvr.Com;
+using JLHHJSvr.Com.Model;
+using JLHHJSvr.Helper;
+using JLHHJSvr.LJException;
+using LJLib.DAL.SQL;
+using LJLib.Net.SPI.Server;
+using LJLib.SQLEX;
+
+namespace JLHHJSvr.Excutor
+{
+    internal sealed class GetSoftBedConfigureListExcutor : ExcutorBase<GetSoftBedConfigureListRequest, GetSoftBedConfigureListResponse>
+    {
+        protected override void ExcuteInternal(GetSoftBedConfigureListRequest request, object state, GetSoftBedConfigureListResponse rslt)
+        {
+            var tokendata = BllHelper.GetToken(request.token);
+            if (tokendata == null)
+            {
+                rslt.ErrMsg = "会话已经中断,请重新登录";
+                return;
+            }
+
+            using (var con = GlobalVar.ConnectionString.NewSqlConnection())
+            using (var cmd = con.CreateCommand())
+            {
+                con.Open();
+
+                var softBedHelper = HelperBase.GetHelper<SoftBedHelper>(cmd);
+
+                if(request.softbed.softbed_id > 0)
+                {
+                    // 模版配置获取
+                    var _softbed = softBedHelper.GetSoftBed(request.softbed.softbed_id, "softbed_id,softbed_code,has_headboard,has_nightstand,has_bedframe");
+
+                    string prefix = $"{_softbed.softbed_code}|";
+                }
+
+                cmd.CommandText = @"SELECT * FROM u_configure_type WHERE LTRIM(RTRIM(configurename)) = @configurename";
+                cmd.Parameters.Clear();
+                cmd.Parameters.AddWithValue("@configurename", "");
+
+            }
+        }
+    }
+}

+ 9 - 0
JLHHJSvr/Excutor/SaveSoftBedQuoteExcutor.cs

@@ -1,6 +1,7 @@
 using System;
 using JLHHJSvr.BLL;
 using JLHHJSvr.Com;
+using JLHHJSvr.Com.Model;
 using JLHHJSvr.Helper;
 using LJLib.Net.SPI.Server;
 using LJLib.SQLEX;
@@ -31,6 +32,14 @@ namespace JLHHJSvr.Excutor
                     {
                         softBedHelper.SaveSoftBed(request.softbed);
 
+                        rslt.softbed = new u_softbed()
+                        {
+                            softbed_id = request.softbed.softbed_id,
+                            softbed_code = request.softbed.softbed_code,
+                            softbed_name = request.softbed.softbed_name,
+                            softbed_relcode = request.softbed.softbed_relcode
+                        };
+
                         cmd.Transaction.Commit();
                     }
                     catch (Exception e)

+ 137 - 23
JLHHJSvr/Helper/SoftBedHelper.cs

@@ -1,4 +1,5 @@
-using JLHHJSvr.BLL;
+using DirectService.Tools;
+using JLHHJSvr.BLL;
 using JLHHJSvr.Com.Model;
 using JLHHJSvr.LJException;
 using JLHHJSvr.Tools;
@@ -11,6 +12,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Web;
+using static JLHHJSvr.Helper.CacheHelper;
 
 namespace JLHHJSvr.Helper
 {
@@ -25,7 +27,7 @@ namespace JLHHJSvr.Helper
         public u_softbed GetSoftBed(int billid,string fields = null)
         {
             fields = fields ?? @"softbed_id,softbed_code,softbed_relcode,softbed_name,deptid,create_date,create_emp,mtrlmode,mtrltype,has_headboard,has_nightstand,has_bedframe,is_template,
-                                template_id,template_code,template_name,commission,taxes,taxrate,other_rate,extras_cost,moneyrate,dscrp,costamt,nottax_factory_cost,nottax_dept_cost,
+                                template_id,template_code,template_name,commission,taxes,taxrate,other_rate,extras_cost,money_type,moneyrate,dscrp,costamt,nottax_factory_cost,nottax_dept_cost,
                                 dept_cost,foreign_cost";
             var bill = new u_softbed() { softbed_id = billid };
 			if (DbSqlHelper.SelectOne(cmd, bill, fields) == 0) return null;
@@ -211,11 +213,11 @@ namespace JLHHJSvr.Helper
 			}
 
 			// TODO:计算价格
-
-			//
+			CalCulateFormula(softbed);
+            //
             var dtNow = context.opdate;
 			var fields = @"softbed_relcode,softbed_name,deptid,mtrlmode,mtrltype,has_headboard,has_nightstand,has_bedframe,is_template,
-                            template_id,template_code,template_name,commission,taxes,taxrate,other_rate,extras_cost,moneyrate,dscrp,costamt,nottax_factory_cost,nottax_dept_cost,
+                            template_id,template_code,template_name,commission,taxes,taxrate,other_rate,extras_cost,money_type,moneyrate,dscrp,costamt,nottax_factory_cost,nottax_dept_cost,
                             dept_cost,foreign_cost";
 
 			var mx_fields = @"softbed_id,printid,pzid,pz_printid,mtrlid,mtrlname,mtrlcode,mtrlmode,unit,has_type,allow_edit,cutting_length,cutting_width,cutting_qty,
@@ -283,6 +285,7 @@ namespace JLHHJSvr.Helper
 			{
                 configureList.Add(new u_configure_type()
 				{
+					contfigtypeid = 0,
                     contfigtypename = $"{prefix}床头",
                     contfigtype = 0,
                     usechflag = 1,
@@ -294,6 +297,7 @@ namespace JLHHJSvr.Helper
 			{
                 configureList.Add(new u_configure_type()
                 {
+                    contfigtypeid = 0,
                     contfigtypename = $"{prefix}床架",
                     contfigtype = 0,
                     usechflag = 1,
@@ -305,6 +309,7 @@ namespace JLHHJSvr.Helper
             {
                 configureList.Add(new u_configure_type()
                 {
+                    contfigtypeid = 0,
                     contfigtypename = $"{prefix}床头柜",
                     contfigtype = 0,
                     usechflag = 1,
@@ -325,6 +330,50 @@ namespace JLHHJSvr.Helper
 				if (cnt > 0) continue;
                 baseInfoHelper.SaveConfigureType(configure);
             }
+        }
+		public List<u_configure_code> GetSoftBedConfigureCodeList(u_softbed softbed)
+		{
+			var codeList = new List<u_configure_code>();
+
+			var selectStr = @"SELECT LTRIM(RTRIM(u_configure_type.configurename)) AS configurename
+								,u_configure_code.typeid
+								,u_configure_code.pzid
+								,u_configure_code.name
+								,u_configure_code.pzcode
+								,u_configure_code.inputtype
+							FROM u_configure_code
+							INNER JOIN u_configure_type ON u_configure_code.typeid = u_configure_type.configureid
+							WHERE LTRIM(RTRIM(u_configure_type.configurename)) IN ()";
+
+			var whereList = new List<string>();
+			var nameList = new List<string>();
+            if (softbed.softbed_id > 0)
+            {
+                // 模版配置获取
+                var _softbed = GetSoftBed(softbed.softbed_id, "softbed_id,softbed_code,has_headboard,has_nightstand,has_bedframe");
+
+                string prefix = $"{_softbed.softbed_code}|";
+
+				if(_softbed.has_headboard == 1)
+				{
+					nameList.Add($"{prefix}床头");
+                }
+
+                if (_softbed.has_nightstand == 1)
+                {
+                    nameList.Add($"{prefix}床头柜");
+                }
+
+                if (_softbed.has_bedframe == 1)
+                {
+                    nameList.Add($"{prefix}床架");
+                }
+            }
+
+			if(nameList.Count > 0)
+			{
+				whereList.Add($"LTRIM(RTRIM(u_configure_type.configurename)) IN {ListEx.getString(nameList)}");
+			}
         }
 		/// <summary>
 		/// 复制软床报价
@@ -407,27 +456,92 @@ namespace JLHHJSvr.Helper
             DbSqlHelper.Update(cmd, "u_softbed", null, softbed, "softbed_id", "flag,audit_date,audit_emp");
         }
 
-        #region 通用公式方法
-        private HashSet<CalCulationFormula> const_formula = new HashSet<CalCulationFormula>();
-        private string ConvertToEnglishSymbols(string input)
-        {
-            input = input.Replace("(", "(")
-                 .Replace(")", ")")
-                 .Replace(",", ",")
-                 .Replace("。", ".")
-                 .Replace(":", ":")
-                 .Replace(";", ";")
-                 .Replace("“", "\"")
-                 .Replace("”", "\"")
-                 .Replace("‘", "'")
-                 .Replace("’", "'");
-
-            return input;
+		public void CalCulateFormula(u_softbed softbed)
+		{
+			InitSoftBed(softbed);
+
+			InitReplaceMents(softbed);
+
+            foreach (var mx in softbed.mxList)
+			{
+				InitMxReplaceMents(softbed, mx);
+			}
         }
-        private void FormatExpression(string expression)
+
+		private void InitSoftBed(u_softbed softbed)
+		{
+            var dept = Cache.GetData<int, u_dept, DeptMapping>(softbed.deptid);
+
+            softbed.moneyrate = softbed.moneyrate <= 0 ? 1 : softbed.moneyrate;
+            softbed.commission = softbed.commission <= 0 ? 1 : softbed.commission;
+            softbed.taxrate = softbed.taxrate <= 0 ? 1 : softbed.taxrate;
+            softbed.other_rate = softbed.other_rate <= 0 ? 1 : softbed.other_rate;
+            softbed.dept_profitrate = softbed.dept_profitrate <= 0 ? 1 : softbed.dept_profitrate;
+
+            // 检查佣金是否小于1
+            if (softbed.commission < 1)
+            {
+                throw new LJCommonException("佣金点数不能小于1!");
+            }
+
+            // 检查税率是否小于1
+            if (softbed.taxrate < 1)
+            {
+                throw new LJCommonException("税率不能小于1!");
+            }
+
+            // 检查额外点数是否小于1
+            if (softbed.other_rate < 1)
+            {
+                throw new LJCommonException("税率不能小于1!");
+            }
+
+            // 检查部门利润率是否为0
+            if (softbed.dept_profitrate == 0)
+            {
+                throw new LJCommonException("部门利润率不能为0!");
+            }
+
+			if(softbed.is_template == 1)
+			{
+				// 使用模板报价
+				softbed.template_id = 0;
+				softbed.template_code = string.Empty;
+				softbed.template_name = string.Empty;
+			}
+        }
+
+		private void InitReplaceMents(u_softbed softbed)
 		{
-            expression = ConvertToEnglishSymbols(expression);
+            //AddKeyValue("不含税出厂价", "【车间成本】*(【工厂利润率】+【外销加点】)",0);
+            //AddKeyValue("部门不含税价", "【不含税出厂价】/【部门利润率】/( 1 - (【佣金点数】- 1))*【额外点数】", 0);
+            //AddKeyValue("税金", "【部门不含税价】* (【税率】-1)", 0);
+            //AddKeyValue("部门含税价", "【部门不含税价】*【税率】", 0);
+            //AddKeyValue("外币价", "【部门含税价】/【汇率】", 0);
+
+            //// 初始变量
+            //AddKeyValue("部门利润率", string.Empty,softbed.dept_profitrate);
+            //AddKeyValue("佣金点数", string.Empty, softbed.commission);
+            //AddKeyValue("额外点数", string.Empty, softbed.other_rate);
+            //AddKeyValue("额外费用", string.Empty, softbed.extras_cost);
+            ////AddKeyValue("FOB", softbed.fob);
+            //AddKeyValue("汇率", string.Empty, softbed.moneyrate);
+            //AddKeyValue("税率", string.Empty, softbed.taxrate);
+        }
+
+        private void InitMxReplaceMents(u_softbed softbed,u_softbed_mx mx)
+        {
+            //AddKeyValue("下料长", string.Empty,mx.cutting_length);
+            //AddKeyValue("下料宽", string.Empty, mx.cutting_width);
+            //AddKeyValue("下料数量", string.Empty, mx.cutting_qty);
+            //AddKeyValue("用料量", string.Empty, mx.useqty);
+            //AddKeyValue("损耗率", string.Empty, mx.loss_rate);
+            //AddKeyValue("材料单价", string.Empty, mx.price);
+            //AddKeyValue("成本单价", string.Empty, mx.cost_price);
         }
+
+        #region 通用公式
+        private CalculateFormula formula = new CalculateFormula();
         #endregion
     }
 }

+ 3 - 0
JLHHJSvr/JLHHJSvr.csproj

@@ -111,6 +111,7 @@
     <Compile Include="Com\GetComputeMattressById.cs" />
     <Compile Include="Com\GetResetWiptype.cs" />
     <Compile Include="Com\GetMattressSubspecs.cs" />
+    <Compile Include="Com\GetSoftBedConfigureList.cs" />
     <Compile Include="Com\GetSoftBedMxList.cs" />
     <Compile Include="Com\ImportMtrlPriceByExcel.cs" />
     <Compile Include="Com\JLH_FetchPrice.cs" />
@@ -340,6 +341,7 @@
     <Compile Include="Excutor\GetFormulaVarListExcutor.cs" />
     <Compile Include="Excutor\GetResetWiptypeExcutor.cs" />
     <Compile Include="Excutor\GetMattressSubspecsExcutor.cs" />
+    <Compile Include="Excutor\GetSoftBedConfigureListExcutor.cs" />
     <Compile Include="Excutor\GetSoftBedMxListExcutor.cs" />
     <Compile Include="Excutor\ImportMtrlPriceByExcelExcutor.cs" />
     <Compile Include="Excutor\JLH_FetchPriceExcutor.cs" />
@@ -603,6 +605,7 @@
     <Compile Include="TextLog\Logger.cs" />
     <Compile Include="TextLog\SyncLogger.cs" />
     <Compile Include="Tools\AutoInit.cs" />
+    <Compile Include="Tools\CalculateFormula.cs" />
     <Compile Include="Tools\ListEx.cs" />
     <Compile Include="Tools\ObjectHelper.cs" />
     <Compile Include="XML\XmlConfig.cs" />

+ 112 - 0
JLHHJSvr/Tools/CalculateFormula.cs

@@ -0,0 +1,112 @@
+using CSUST.Data.Expr;
+using JLHHJSvr.Com.Model;
+using JLHHJSvr.LJException;
+using JLHHJSvr.LJFramework.Tools;
+using NPOI.SS.Formula.Functions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JLHHJSvr.Tools
+{
+    public class CalculateFormula
+    {
+        private HashSet<FormulaItem> _formula;
+        private HashSet<FormulaItem> _const;
+
+        public CalculateFormula() 
+        {
+            _formula = new HashSet<FormulaItem>();
+            _const = new HashSet<FormulaItem>();
+        }
+
+        public void AddFormulaItem(FormulaItem item) 
+        {
+            if(!_formula.Add(item))
+            {
+                _formula.Remove(item);
+                _formula.Add(item);
+            }
+        }
+        public void AddConstFormulaItem(FormulaItem item)
+        {
+            if (!_const.Add(item))
+            {
+                _const.Remove(item);
+                _const.Add(item);
+            }
+        }
+
+        public void AddFormulaItem(string name,object value)
+        {
+            AddConstFormulaItem(new FormulaItem() { formula_name = name, value = value });
+        }
+
+        public void AddFormulaItem(string name, string formula)
+        {
+            AddFormulaItem(new FormulaItem() { formula_name = name, formula = formula });
+        }
+
+        private string ConvertToEnglishSymbols(string input)
+        {
+            input = input.Replace("(", "(")
+                 .Replace(")", ")")
+                 .Replace(",", ",")
+                 .Replace("。", ".")
+                 .Replace(":", ":")
+                 .Replace(";", ";")
+                 .Replace("“", "\"")
+                 .Replace("”", "\"")
+                 .Replace("‘", "'")
+                 .Replace("’", "'");
+
+            return input;
+        }
+        private void FormatExpression(FormulaItem formula)
+        {
+            formula.formula = ConvertToEnglishSymbols(formula.formula);
+        }
+        /// <summary>
+        /// 公式计算
+        /// </summary>
+        /// <param name="expression"></param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        private void Calculate(FormulaItem formula)
+        {
+            FormatExpression(formula);
+
+            try
+            {
+                formula.value = LJExprParser.Parse(formula.formula).Result;
+            }
+            catch (Exception ex)
+            {
+                throw new LJCommonException($"计算{formula.formula_name}公式错误: {ex.Message}");
+            }
+        }
+        /// <summary>
+        /// Sql公式计算
+        /// </summary>
+        /// <param name="expression"></param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        private void SqlCalculate(FormulaItem formula)
+        {
+            FormatExpression(formula);
+
+            try
+            {
+                //cmd.CommandText = $@"{formula.formula}";
+                //cmd.Parameters.Clear();
+                //return cmd.ExecuteScalar();
+            }
+            catch (Exception ex)
+            {
+                throw new LJCommonException($"计算{formula.formula_name}公式错误: {ex.Message}");
+            }
+        }
+    }
+}

+ 1 - 1
JLHWEB/src/components/LjVxeTable/index.vue

@@ -1404,7 +1404,7 @@ const setEnumMap = async (col: ColumnProps) => {
     }
     return enumMap.value.set(col.field!, _enum);
   }
-  const { data } = await col.enum();
+  const data = await col.enum();
   console.log("enumMap data col.field,:>> ", col.field, data);
   enumMap.value.set(col.field!, data);
 };

+ 2 - 0
JLHWEB/src/stores/modules/auth.ts

@@ -13,6 +13,7 @@ import { baseRouter } from "@/routers/modules/baseRouter";
 import { salePriceRouter } from "@/routers/modules/salePriceRouter";
 import { mattressQtuoteRouter } from "@/routers/modules/mattressQtuoteRouter";
 import { bednetQtuoteRouter } from "@/routers/modules/bednetQtuoteRouter";
+import { softbedQuoteRouter } from "@/routers/modules/softbedQuoteRouter";
 import { semifinprodQuoteRouter } from "@/routers/modules/selmifinprodRouter";
 import { erpApiRouter } from "@/routers/modules/erpApiRouter";
 import { useUserStore } from "@/stores/modules/user";
@@ -82,6 +83,7 @@ export const useAuthStore = defineStore({
         salePriceRouter,
         mattressQtuoteRouter,
         bednetQtuoteRouter,
+        softbedQuoteRouter,
         semifinprodQuoteRouter,
         erpApiRouter
       );

+ 0 - 10
JLHWEB/src/views/quote/bednetQuote/detail.vue

@@ -102,21 +102,11 @@ import { useI18n } from "vue-i18n";
 import { useHooks } from "./hooks/index";
 import { useAuthButtons } from "@/hooks/useAuthButtons";
 import LjVxeTable from "@/components/LjVxeTable/index.vue";
-// import { cloneDeep } from "lodash-es";
 import { useRoute, useRouter } from "vue-router";
-import { CommonDynamicSelect, GetFormulaCompute } from "@/api/modules/common";
 import { SaveBedNet, AuditBedNet, DeleteBedNet } from "@/api/modules/quote";
-// import ToastFormula from "@/components/ToastWidget/Formula/index.vue";
-import { TYPE, useToast, POSITION } from "vue-toastification";
 import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
-// import { ArrowDown } from "@element-plus/icons-vue";
-// import { calculateFormula } from "@/utils/index";
 import MtrldefDialog from "@/views/system/selector/mtrldef/index.vue";
 import SpringDialog from "@/views/system/selector/spring/index.vue";
-// import LjDrawerQuoteList from "./components/QuoteList.vue";
-// import mittBus from "@/utils/mittBus";
-// import { MittEnum } from "@/enums/mittEnum";
-// import { getCurrentRecords } from "@/utils/index";
 import { useUserStore } from "@/stores/modules/user";
 // import { getBedNetAreaList } from "@/api/modules/basicinfo";
 import AllFormula from "./components/AllFormula.vue";

+ 1 - 1
JLHWEB/src/views/quote/softbedQuote/components/BedConfigModal.vue

@@ -122,7 +122,7 @@ const onConfirm = () => {
   emit("submit", newParts);
 };
 
-const closed = () => emit("closed");
+const closed = () => emit("cancel");
 </script>
 
 <style lang="scss">

+ 94 - 9
JLHWEB/src/views/quote/softbedQuote/detail.vue

@@ -14,7 +14,7 @@
   >
     <template #HeadBoard>
       <LjVxeTable
-        ref="VxeTableMxRef"
+        ref="VxeTableHeadBoardMxRef"
         row-key="key"
         table-cls=""
         :data="headBoardMx"
@@ -23,11 +23,17 @@
         :auto-load-layout="false"
         :request-auto="false"
       >
+        <template #tableHeader>
+          <el-space wrap v-if="orderStatus">
+            <el-button type="primary" @click="toAddMx(VxeTableHeadBoardMxRef)">{{ t("common.addText") }}</el-button>
+            <el-button type="danger" @click="toDelMx(VxeTableHeadBoardMxRef)">{{ t("common.delText") }}</el-button>
+          </el-space>
+        </template>
       </LjVxeTable>
     </template>
     <template #NightStand>
       <LjVxeTable
-        ref="VxeTableMxRef"
+        ref="VxeTableNightStandMxRef"
         row-key="key"
         table-cls=""
         :data="nightStandMx"
@@ -36,11 +42,17 @@
         :auto-load-layout="false"
         :request-auto="false"
       >
+        <template #tableHeader>
+          <el-space wrap v-if="orderStatus">
+            <el-button type="primary" @click="toAddMx(VxeTableNightStandMxRef)">{{ t("common.addText") }}</el-button>
+            <el-button type="danger" @click="toDelMx(VxeTableNightStandMxRef)">{{ t("common.delText") }}</el-button>
+          </el-space>
+        </template>
       </LjVxeTable>
     </template>
     <template #BedFrame>
       <LjVxeTable
-        ref="VxeTableMxRef"
+        ref="VxeTableBedFrameMxRef"
         row-key="key"
         table-cls=""
         :data="bedFrameMx"
@@ -49,24 +61,39 @@
         :auto-load-layout="false"
         :request-auto="false"
       >
+        <template #tableHeader>
+          <el-space wrap v-if="orderStatus">
+            <el-button type="primary" @click="toAddMx(VxeTableBedFrameMxRef)">{{ t("common.addText") }}</el-button>
+            <el-button type="danger" @click="toDelMx(VxeTableBedFrameMxRef)">{{ t("common.delText") }}</el-button>
+          </el-space>
+        </template>
       </LjVxeTable>
     </template>
   </LjDetail>
+  <BedConfigModal
+    v-model="isModalVisible"
+    v-model:showHeadboard="showHeadboard"
+    v-model:showNightstand="showNightstand"
+    v-model:showBedframe="showBedframe"
+    v-model:partsConfig="partsConfig"
+    :configItemOptions="allConfigItemOptions"
+    :configValueOptionsMap="configValueOptionsMap"
+    @submit="onConfirmConfigureDialog"
+    @cancel="isModalVisible = false"
+  />
 </template>
 
 <script setup lang="tsx" name="softBedQuoteDetail">
 import { ref, watch, reactive, inject, onMounted } from "vue";
 import { DwnameEnum } from "@/enums/dwnameEnum";
-import {} from "@/api/modules/quote";
 import LjDetail from "@/components/LjDetail/index.vue";
 import { DetailProp } from "@/components/LjDetail/interface";
 import { useI18n } from "vue-i18n";
 import { useRoute, useRouter } from "vue-router";
 import { useAuthButtons } from "@/hooks/useAuthButtons";
-import { CommonDynamicSelect } from "@/api/modules/common";
-import { ElMessage, ElMessageBox } from "element-plus";
 import { useHooks } from "./hooks/index";
 import { useUserStore } from "@/stores/modules/user";
+import BedConfigModal from "./components/BedConfigModal.vue";
 
 const { t } = useI18n();
 const route = useRoute();
@@ -74,22 +101,72 @@ const router = useRouter();
 const {
   orderStatus,
   LjDetailRef,
-  VxeTableMxRef,
+  VxeTableHeadBoardMxRef,
+  VxeTableNightStandMxRef,
+  VxeTableBedFrameMxRef,
   columns,
   columnsMx,
   softBed,
   headBoardMx,
   nightStandMx,
   bedFrameMx,
+  isModalVisible,
+  showHeadboard,
+  showBedframe,
+  showNightstand,
   detail_getData,
+  toAddMx,
+  toDelMx,
+  onSave,
   onAudit,
   onCAudit,
-  onDelete
+  onDelete,
+  onConfirmConfigureDialog
 } = useHooks(t);
 const { CheckPower, CheckOption, buttonNew, buttonDefault } = useAuthButtons(t);
 
 const initParams = ref({ billid: 0 as Number });
 
+const allConfigItemOptions = reactive([
+  { pzid: 101, pzname: "颜色" },
+  { pzid: 201, pzname: "材质" },
+  { pzid: 301, pzname: "款式" },
+  { pzid: 401, pzname: "尺寸" },
+  { pzid: 501, pzname: "填充物" },
+  { pzid: 601, pzname: "靠背调节" }
+]);
+
+const configValueOptionsMap = reactive({
+  101: [
+    { printid: 1, pznamemx: "白色" },
+    { printid: 2, pznamemx: "红色" }
+  ],
+  201: [
+    { printid: 1, pznamemx: "皮质" },
+    { printid: 2, pznamemx: "布艺" }
+  ],
+  301: [{ printid: 1, pznamemx: "简约款" }],
+  401: [{ printid: 1, pznamemx: "1.8米" }],
+  501: [{ printid: 1, pznamemx: "记忆棉" }],
+  601: [{ printid: 1, pznamemx: "不可调节" }]
+});
+
+// 父组件维护 partsConfig,Modal 每次打开都会使用同一个对象(记忆性)
+const partsConfig = reactive({
+  headboard: [
+    { pzid: 101, selectedValue: "白色" },
+    { pzid: 201, selectedValue: "皮质" }
+  ],
+  nightstand: [
+    { pzid: 101, selectedValue: "白色" },
+    { pzid: 301, selectedValue: "欧式款" }
+  ],
+  bedframe: [
+    { pzid: 101, selectedValue: "灰色" },
+    { pzid: 401, selectedValue: "1.8米" }
+  ]
+});
+
 const tabRemove: Function = inject("tabRemove") as Function;
 const { userInfo } = useUserStore();
 const loadingStatus = reactive({
@@ -199,7 +276,15 @@ const orderDefaultAction = [
       }
       return "";
     },
-    clickFunc: () => {}
+    clickFunc: () => {
+      onSave(res => {
+        if (res.softbed.softbed_id) {
+          router.replace(`/softbedQuote/detail?id=${res.softbed.softbed_id}&code=${res.softbed.softbed_code}`);
+        } else {
+          router.replace("/softbedQuote");
+        }
+      });
+    }
   }),
   buttonDefault({
     label: t("common.add"),

+ 263 - 42
JLHWEB/src/views/quote/softbedQuote/hooks/index.tsx

@@ -1,12 +1,14 @@
 import { ref, reactive, computed, toRefs, nextTick } from "vue";
 import { ColumnProps } from "@/components/LjVxeTable/interface";
-import { GetSoftBedMxList } from "@/api/modules/quote";
+import { GetSoftBedMxList, SaveSoftBedQuote } from "@/api/modules/quote";
 import { ALLOW_EDIT_STATE } from "@/config/index";
-import { ElButton, ElMessage, ElMessageBox, ElRow, ElCol } from "element-plus";
+import { ElButton, ElMessage, ElMessageBox, ElRow, ElCol, ElNotification } from "element-plus";
 import { AuditSoftBedQuote, DeleteSoftBedQuote } from "@/api/modules/quote";
 import { getDeptList } from "@/api/modules/saleprice";
 import { CommonDynamicSelect } from "@/api/modules/common";
 import SoftBedSelect from "@/views/system/selector/softbedTemplate/select.vue";
+import { cloneDeep } from "lodash-es";
+import { getCurrentRecords } from "@/utils/index";
 interface defaultState {
   /**
    * @description 单据当前状态
@@ -23,7 +25,18 @@ interface defaultState {
   /**
    * @description 详情页明细表格Ref
    */
-  VxeTableMxRef: any;
+  VxeTableHeadBoardMxRef: any;
+  /**
+   * @description 详情页明细表格Ref
+   */
+  VxeTableNightStandMxRef: any;
+  /**
+   * @description 详情页明细表格Ref
+   */
+  VxeTableBedFrameMxRef: any;
+  /**
+   *
+   */
   initParams: any;
   /**
    * @description 详情页主表数据
@@ -45,6 +58,30 @@ interface defaultState {
    * @description 详情页主表明细数据-床架
    */
   bedFrameMx: any[];
+  /**
+   * @description 详情页模板报价弹窗对象
+   */
+  SoftBedTemplateDialogRef: any;
+  /**
+   * @description 详情页模板报价弹窗入参
+   */
+  SoftBedTemplateDialogProps: any;
+  /**
+   * @description 详情页部件配置选择弹窗
+   */
+  isModalVisible: boolean;
+  /**
+   * @description 详情页部件配置选择弹窗
+   */
+  showHeadboard: boolean;
+  /**
+   * @description 详情页部件配置选择弹窗
+   */
+  showNightstand: boolean;
+  /**
+   * @description 详情页部件配置选择弹窗
+   */
+  showBedframe: boolean;
 }
 
 /**
@@ -56,12 +93,20 @@ export const useHooks = (t?: any) => {
     orderStatus: "",
     VxeTableRef: null,
     LjDetailRef: null,
-    VxeTableMxRef: null,
-    softBed: null,
-    softBedMx: null,
-    headBoardMx: null,
-    nightStandMx: null,
-    bedFrameMx: null,
+    VxeTableHeadBoardMxRef: null,
+    VxeTableBedFrameMxRef: null,
+    VxeTableNightStandMxRef: null,
+    softBed: {},
+    softBedMx: [],
+    headBoardMx: [],
+    nightStandMx: [],
+    bedFrameMx: [],
+    SoftBedTemplateDialogRef: null,
+    SoftBedTemplateDialogProps: null,
+    isModalVisible: false,
+    showHeadboard: false,
+    showNightstand: false,
+    showBedframe: false,
     initParams: { arg_softbed_id: 0 }
   });
   // 表格配置项
@@ -91,9 +136,11 @@ export const useHooks = (t?: any) => {
       title: "部门",
       enum: () =>
         getDeptList({}).then(res => {
-          return res.datatable;
+          return res.datatable.map(t => {
+            return { ...t, label: t.deptname, value: t.deptid };
+          });
         }),
-      fieldNames: { label: "deptname", value: "deptid" },
+      // fieldNames: { label: "deptname", value: "deptid" },
       search: {
         el: "select",
         key: "arg_deptid",
@@ -133,6 +180,10 @@ export const useHooks = (t?: any) => {
       datatype: "checkbox",
       basicinfo: {
         el: "checkbox",
+        props: {
+          trueValue: 1,
+          falseValue: 0
+        },
         span: 1,
         row: 1,
         order: 2,
@@ -154,15 +205,35 @@ export const useHooks = (t?: any) => {
       field: "template_code",
       title: "模板编号",
       basicinfo: {
+        el: "select",
         span: 1,
         row: 1,
         order: 4,
         group: "单据信息",
-        editable: (scope: any) => {
-          if (ALLOW_EDIT_STATE.includes(scope.status) && Number(scope.searchParam.is_template)) {
-            return true;
-          }
-          return false;
+        render: (scope: any) => {
+          const { column, searchParam: row, status } = scope;
+          let params = {
+            arg_template_id: row.template_id
+          };
+          let _disabled = !(ALLOW_EDIT_STATE.includes(state.orderStatus) && !Number(scope.searchParam.is_template));
+          return (
+            <>
+              <SoftBedSelect
+                value={row.template_code}
+                {...params}
+                clearable
+                disabled={_disabled}
+                placeholder={row.template_code}
+                onOpenModal={() => fModelChoseTemplate(row, params)}
+                onSelect={(val: any) => rModelSetTemplate(row, val)}
+                onClear={() => rModelClearTemplate(row)}
+              >
+                {{
+                  label: () => row.template_code
+                }}
+              </SoftBedSelect>
+            </>
+          );
         }
       }
     },
@@ -171,23 +242,24 @@ export const useHooks = (t?: any) => {
       title: "报价名称",
       basicinfo: {
         el: "input",
+        editable: ALLOW_EDIT_STATE,
         span: 1,
         row: 1,
         order: 5,
-        group: "单据信息",
-        editable: ALLOW_EDIT_STATE
+        group: "单据信息"
       }
     },
     {
       field: "template_name",
       title: "模板名称",
       basicinfo: {
+        el: "input",
         span: 1,
         row: 1,
         order: 6,
         group: "单据信息",
         editable: (scope: any) => {
-          if (ALLOW_EDIT_STATE.includes(scope.status) && Number(scope.searchParam.is_template)) {
+          if (ALLOW_EDIT_STATE.includes(scope.status) && !Number(scope.searchParam.is_template)) {
             return true;
           }
           return false;
@@ -199,11 +271,11 @@ export const useHooks = (t?: any) => {
       title: "报价编码",
       basicinfo: {
         el: "input",
+        editable: ALLOW_EDIT_STATE,
         span: 1,
         row: 1,
         order: 7,
-        group: "单据信息",
-        editable: ALLOW_EDIT_STATE
+        group: "单据信息"
       }
     },
     {
@@ -449,7 +521,7 @@ export const useHooks = (t?: any) => {
 
           return (
             <el-select
-              v-model={scope.searchParam.if_moneyrate}
+              v-model={scope.searchParam.money_type}
               v-slots={slotprefix}
               class="select-text-right"
               disabled={_disabled}
@@ -779,34 +851,90 @@ export const useHooks = (t?: any) => {
    */
   const detail_getData = async (params: any) => {
     const result = await GetSoftBedMxList(params);
-    detail_dataCallback(result);
-  };
-
-  const detail_dataCallback = (data: any) => {
     if (state.orderStatus === "new") {
-      data.softbed.taxrate = 1;
+      result.softbed.taxrate = 1;
     }
 
-    state.softBed = [data.softbed];
-    state.softBedMx = data.mxList;
-    state.headBoardMx = data.mxList.filter(item => item.has_type === 1);
-    state.nightStandMx = data.mxList.filter(item => item.has_type === 2);
-    state.bedFrameMx = data.mxList.filter(item => item.has_type === 4);
+    state.softBed = [result.softbed];
+    state.softBedMx = result.mxList;
+    state.headBoardMx = result.mxList.filter(item => item.has_type === 1);
+    state.nightStandMx = result.mxList.filter(item => item.has_type === 2);
+    state.bedFrameMx = result.mxList.filter(item => item.has_type === 4);
   };
-
   /**
    * 打开部件配置弹窗
    */
-  const onOpenConfigureDialog = () => {};
+  const onOpenConfigureDialog = () => {
+    const { _mainData, enumMap } = state.LjDetailRef;
+    nextTick(() => {
+      state.showHeadboard = Boolean(_mainData.has_headboard);
+      state.showNightstand = Boolean(_mainData.has_nightstand);
+      state.showBedframe = Boolean(_mainData.has_bedframe);
+
+      state.isModalVisible = true;
+    });
+  };
   /**
    * 确认部件配置项值
    * @param params 返回内容
    */
-  const onConfirmConfigureDialog = (params: any) => {};
+  const onConfirmConfigureDialog = (params: any) => {
+    const { _mainData } = state.LjDetailRef;
+    nextTick(() => {
+      _mainData.has_headboard = Number(state.showHeadboard);
+      _mainData.has_nightstand = Number(state.showNightstand);
+      _mainData.has_bedframe = Number(state.showBedframe);
+
+      state.isModalVisible = false;
+    });
+  };
   /**
    * 保存报价
    */
-  const onSave = () => {};
+  const onSave = async cb => {
+    const { _mainData } = state.LjDetailRef;
+    const headboard_table = state.VxeTableHeadBoardMxRef.element.getTableData();
+    const nightstand_table = state.VxeTableNightStandMxRef.element.getTableData();
+    const bedframe_table = state.VxeTableBedFrameMxRef.element.getTableData();
+
+    const _softbed = cloneDeep(_mainData);
+    const _mxList = [];
+    _softbed.mxList = _mxList;
+
+    if (headboard_table && headboard_table.length > 0) _mxList.push(headboard_table);
+    if (nightstand_table && nightstand_table.length > 0) _mxList.push(nightstand_table);
+    if (bedframe_table && bedframe_table.length > 0) _mxList.push(bedframe_table);
+
+    transformData(_softbed);
+
+    const params: any = {
+      softbed: _softbed
+    };
+
+    try {
+      await SaveSoftBedQuote(params)
+        .then((res: any) => {
+          ElNotification({
+            title: "温馨提示",
+            message: t("sys.api.sueccessToSave"),
+            type: "success"
+          });
+
+          cb && cb(res);
+        })
+        .catch(error => {
+          console.log("error !! :>> ", error);
+        });
+    } catch (error) {
+      ElMessage.error(t("sys.api.operationFailed"));
+    }
+  };
+
+  const transformData = (data: any) => {
+    for (let key in data) {
+      if (typeof data[key] === "boolean") data[key] = Number(data[key]);
+    }
+  };
   /**
    * 审核报价
    */
@@ -819,7 +947,7 @@ export const useHooks = (t?: any) => {
       .then(() => {
         AuditSoftBedQuote({ list, type: 1 }).then(() => {
           ElMessage.success(t("sys.api.operationSuccess"));
-          state.VxeTableMxRef.refresh();
+          state.VxeTableRef.refresh();
         });
       })
       .catch((e: TypeError) => {
@@ -841,7 +969,7 @@ export const useHooks = (t?: any) => {
       .then(() => {
         AuditSoftBedQuote({ list, type: 0 }).then(() => {
           ElMessage.success(t("sys.api.operationSuccess"));
-          state.VxeTableMxRef.refresh();
+          state.VxeTableRef.refresh();
         });
       })
       .catch((e: TypeError) => {
@@ -864,7 +992,7 @@ export const useHooks = (t?: any) => {
         DeleteSoftBedQuote({ list }).then(() => {
           ElMessage.success(t("sys.api.operationSuccess"));
           cb && cb();
-          state.VxeTableMxRef.refresh();
+          state.VxeTableRef.refresh();
         });
       })
       .catch((e: TypeError) => {
@@ -898,8 +1026,8 @@ export const useHooks = (t?: any) => {
       let depItem = deptEnum.find((item: any) => item.deptid == _mainData.deptid);
       if (depItem) {
         let _moneyrate = !depItem.moneyrate || Number(depItem.moneyrate) == 0 ? 1 : depItem.moneyrate;
-        if (val == 0 || !_mainData.if_moneyrate) {
-          _mainData.if_moneyrate = 0;
+        if (val == 0 || !_mainData.money_type) {
+          _mainData.money_type = 0;
           _mainData.moneyrate = 1;
         } else {
           _mainData.moneyrate = _moneyrate;
@@ -913,16 +1041,109 @@ export const useHooks = (t?: any) => {
     data.taxrate = val;
   };
 
+  /**
+   * @description 弹窗模块:客户选择
+   * @param data 当前数据
+   * @param status 当前订单状态
+   * @returns Promise
+   */
+  const fModelChoseTemplate = (data: any, params: any) => {
+    return new Promise((resolve, reject) => {
+      let _params = {
+        arg_search: ""
+      };
+      state.SoftBedTemplateDialogProps = {
+        onSubmit: (res: any) => {
+          // submit
+          nextTick(() => {
+            rModelSetTemplate(data, res.value[0]);
+            resolve(1);
+          });
+        },
+        onCancel: (error: any) => {
+          // cancel 回调
+        }
+      };
+      state.SoftBedTemplateDialogRef.show(_params);
+    });
+  };
+  /**
+   * @description 数据赋值: 联系人
+   * @param data 当前数据
+   * @param item 当前选择的数据
+   */
+  const rModelSetTemplate = (data: any, item: any) => {
+    data.template_id = Number(item.softbed_id);
+    data.template_code = item.softbed_code;
+    data.template_name = item.softbed_name;
+  };
+  /**
+   * 清空选择参数
+   * @param data
+   */
+  const rModelClearTemplate = (data: any) => {
+    data.template_id = 0;
+    data.template_code = "";
+    data.template_name = "";
+  };
+
+  const toAddMx = async (tableRef: any) => {
+    const { _mainData } = state.LjDetailRef;
+    const $table = tableRef.element;
+    if ($table) {
+      // 新增
+      const records = {
+        softbed_id: _mainData.softbed_id,
+        has_type: getHasType(tableRef),
+        mtrlname: "",
+        mtrlcode: "",
+        mtrlmode: "",
+        unit: "",
+        allow_edit: 0,
+        cutting_length: 0,
+        cutting_width: 0,
+        cutting_qty: 0
+      };
+      const { row } = await $table.insertAt(records, -1);
+      await $table.setCurrentRow(row);
+    }
+  };
+
+  const toDelMx = (tableRef: any) => {
+    const { $table } = getCurrentRecords(tableRef);
+    ElMessageBox.confirm(`是否确定要删除明细吗?`, "询问", {
+      confirmButtonText: t("common.delText"),
+      cancelButtonText: "否",
+      type: "error"
+    })
+      .then(() => {
+        $table.removeCurrentRow();
+      })
+      .catch((e: TypeError) => {
+        ElMessage({
+          type: "info",
+          message: "操作取消"
+        });
+      });
+  };
+
+  const getHasType = (tableRef: any) => {
+    return tableRef === state.VxeTableHeadBoardMxRef ? 1 : tableRef === state.VxeTableNightStandMxRef ? 2 : 4;
+  };
+
   return {
     ...toRefs(state),
     columns,
     columnsMx,
     detail_getData,
+    toAddMx,
+    toDelMx,
     onSave,
     onAudit,
     onCAudit,
     onDelete,
     onCopyQuote,
-    onShowFormula
+    onShowFormula,
+    onConfirmConfigureDialog
   };
 };

+ 0 - 1
JLHWEB/src/views/quote/softbedQuote/index.vue

@@ -49,7 +49,6 @@ import { ElMessage, ElMessageBox } from "element-plus";
 import { detailAction } from "@/components/LjDetail/interface";
 import { useUserStore } from "@/stores/modules/user";
 import { getCurrentRecords } from "@/utils/index";
-import BedConfigModal from "./components/BedConfigModal.vue";
 
 const { t } = useI18n();
 const router = useRouter();

+ 1 - 5
JLHWEB/src/views/system/selector/softbedTemplate/select.vue

@@ -34,9 +34,6 @@
       :label="item.softbed_name"
       :value="item"
       class="lj-select__table pl-10 pr-10"
-      :class="{
-        'w-full': item.label
-      }"
     >
       <template v-if="item.label">
         <div class="table-tr w-full text-center">{{ item.label }}</div>
@@ -71,7 +68,6 @@ import { ref, computed } from "vue";
 import { CommonDynamicSelect } from "@/api/modules/common";
 import { DwnameEnum } from "@/enums/dwnameEnum";
 import LjSelectorSelect from "@/components/LjSelector/select.vue";
-import { useUserStore } from "@/stores/modules/user";
 
 interface ProTableProps {
   value: any;
@@ -80,9 +76,9 @@ interface ProTableProps {
 
 // 默认值
 const props = withDefaults(defineProps<ProTableProps>(), {});
-const { userInfo } = useUserStore();
 const emit = defineEmits(["select", "update:value", "openModal"]);
 const loading = ref(false);
+const options = ref<any[]>([]);
 
 const remoteMethod = async (queryString: string) => {
   loading.value = true;