New file |
| | |
| | | package com.zy.crm.manager.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.baomidou.mybatisplus.plugins.Page; |
| | | import com.core.common.DateUtils; |
| | | import com.zy.crm.common.service.OssService; |
| | | import com.zy.crm.manager.entity.Contract; |
| | | import com.zy.crm.manager.entity.ContractSales; |
| | | import com.zy.crm.manager.entity.PriOnline; |
| | | import com.zy.crm.manager.service.ContractSalesService; |
| | | import com.zy.crm.manager.service.ContractService; |
| | | import com.core.annotations.ManagerAuth; |
| | | import com.core.common.BaseRes; |
| | | import com.core.common.Cools; |
| | | import com.core.common.R; |
| | | import com.core.domain.KeyValueVo; |
| | | import com.zy.crm.common.web.BaseController; |
| | | import com.zy.crm.manager.utils.ChineseNumberUtils; |
| | | import com.zy.crm.manager.utils.WordUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.core.io.InputStreamResource; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.util.ClassUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | | public class ContractController extends BaseController { |
| | | |
| | | @Autowired |
| | | private ContractService contractService; |
| | | @Autowired |
| | | private ContractSalesService contractSalesService; |
| | | @Autowired |
| | | private OssService ossService; |
| | | |
| | | @RequestMapping(value = "/contract/{id}/auth") |
| | | @ManagerAuth |
| | | public R get(@PathVariable("id") String id) { |
| | | return R.ok(contractService.selectById(String.valueOf(id))); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/list/auth") |
| | | @ManagerAuth |
| | | public R list(@RequestParam(defaultValue = "1")Integer curr, |
| | | @RequestParam(defaultValue = "10")Integer limit, |
| | | @RequestParam(required = false)String orderByField, |
| | | @RequestParam(required = false)String orderByType, |
| | | @RequestParam(required = false)String condition, |
| | | @RequestParam Map<String, Object> param){ |
| | | EntityWrapper<Contract> wrapper = new EntityWrapper<>(); |
| | | excludeTrash(param); |
| | | convert(param, wrapper); |
| | | allLike(Contract.class, param.keySet(), wrapper, condition); |
| | | if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));} |
| | | return R.ok(contractService.selectPage(new Page<>(curr, limit), wrapper)); |
| | | } |
| | | |
| | | private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){ |
| | | for (Map.Entry<String, Object> entry : map.entrySet()){ |
| | | String val = String.valueOf(entry.getValue()); |
| | | if (val.contains(RANGE_TIME_LINK)){ |
| | | String[] dates = val.split(RANGE_TIME_LINK); |
| | | wrapper.ge(entry.getKey(), DateUtils.convert(dates[0])); |
| | | wrapper.le(entry.getKey(), DateUtils.convert(dates[1])); |
| | | } else { |
| | | wrapper.like(entry.getKey(), val); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/add/auth") |
| | | @ManagerAuth |
| | | public R add(Contract contract) { |
| | | contract.setCreateBy(getUserId()); |
| | | contract.setCreateTime(new Date()); |
| | | contractService.insert(contract); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/update/auth") |
| | | @ManagerAuth |
| | | public R update(Contract contract){ |
| | | if (Cools.isEmpty(contract) || null==contract.getId()){ |
| | | return R.error(); |
| | | } |
| | | contract.setUpdateBy(getUserId()); |
| | | contract.setUpdateTime(new Date()); |
| | | contractService.updateById(contract); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | contractService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/generate/auth") |
| | | @ManagerAuth |
| | | public ResponseEntity<InputStreamResource> generate(@RequestParam Integer id, |
| | | @RequestParam String contractTemplate){ |
| | | try { |
| | | /////////////////////////生成合同数据///////////////////////// |
| | | Contract contract = contractService.selectById(id); |
| | | if (contract == null) { |
| | | return null; |
| | | } |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("{{customer}}", contract.getCustomer()); |
| | | map.put("{{address}}", contract.getAddress()); |
| | | map.put("{{company}}", contract.getCompany()); |
| | | map.put("{{companyAddress}}", contract.getCompanyAddress()); |
| | | map.put("{{taxNum}}", contract.getTaxNum()); |
| | | map.put("{{bank}}", contract.getBank()); |
| | | map.put("{{bankNum}}", contract.getBankNum()); |
| | | map.put("{{city}}", contract.getCity()); |
| | | map.put("{{shippingAddress}}", contract.getShippingAddress()); |
| | | map.put("{{shippingName}}", contract.getShippingName()); |
| | | map.put("{{shippingPhone}}", contract.getShippingPhone()); |
| | | map.put("{{email}}", contract.getEmail()); |
| | | map.put("{{boss}}", contract.getBoss()); |
| | | map.put("{{priceChinese}}", ChineseNumberUtils.numberToChinese(contract.getPrice())); |
| | | map.put("{{priceSci}}", WordUtils.formatNumberForAccounting(contract.getPrice())); |
| | | |
| | | SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); |
| | | map.put("{{now}}", format.format(new Date())); |
| | | /////////////////////////生成合同数据///////////////////////// |
| | | |
| | | /////////////////////////生成Tab表格数据///////////////////////// |
| | | List<ContractSales> contractSales = contractSalesService.selectByContractId(contract.getId()); |
| | | List<List<String>> tabParam = new ArrayList<>(); |
| | | ArrayList<String> tabTitle = new ArrayList<>(); |
| | | tabTitle.add("序号"); |
| | | tabTitle.add("品名"); |
| | | tabTitle.add("数量"); |
| | | tabTitle.add("单位"); |
| | | tabTitle.add("单价(元)"); |
| | | tabTitle.add("合计(元)"); |
| | | tabTitle.add("备注"); |
| | | tabParam.add(tabTitle); |
| | | int idx = 1;//tab序号 |
| | | double totalPrice = 0D; |
| | | for (ContractSales contractSale : contractSales) { |
| | | ArrayList<String> list = new ArrayList<>(); |
| | | list.add(String.valueOf(idx)); |
| | | list.add(contractSale.getName()); |
| | | list.add(String.valueOf(contractSale.getNum())); |
| | | list.add(contractSale.getUnit()); |
| | | list.add(WordUtils.formatNumberForAccounting(contractSale.getUnitPrice())); |
| | | list.add(WordUtils.formatNumberForAccounting(contractSale.getTotalPrice())); |
| | | list.add(contractSale.getMemo()); |
| | | tabParam.add(list); |
| | | totalPrice += contractSale.getTotalPrice(); |
| | | idx++;//序号+1 |
| | | } |
| | | |
| | | //tab最后合计栏 |
| | | ArrayList<String> tabFooter = new ArrayList<>(); |
| | | tabFooter.add("合计(大写金额):" + ChineseNumberUtils.numberToChinese(totalPrice)); |
| | | tabFooter.add("");//合并单元格 |
| | | tabFooter.add("");//合并单元格 |
| | | tabFooter.add("");//合并单元格 |
| | | tabFooter.add("合计:" + WordUtils.formatNumberForAccounting(totalPrice)); |
| | | tabFooter.add("");//合并单元格 |
| | | tabFooter.add("");//合并单元格 |
| | | tabParam.add(tabFooter); |
| | | /////////////////////////生成Tab表格数据///////////////////////// |
| | | |
| | | String fileName = this.getClass().getClassLoader().getResource("contractTemplate/" + contractTemplate + ".docx").getPath();//获取文件路径 |
| | | return WordUtils.generate(fileName, map, tabParam); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/upload/auth") |
| | | @ManagerAuth |
| | | public R upload(@RequestParam("id") Integer id, |
| | | @RequestParam("file") MultipartFile[] files) throws IOException { |
| | | Contract contract = contractService.selectById(id); |
| | | if (contract == null) { |
| | | return R.error(); |
| | | } |
| | | |
| | | MultipartFile file = files[0]; |
| | | SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss"); |
| | | String path = ClassUtils.getDefaultClassLoader().getResource("contractTemplate/upload").getPath(); |
| | | //文件后缀名 |
| | | String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); |
| | | //上传文件名 |
| | | String filename = format.format(new Date()) + suffix; |
| | | //最终文件路径 |
| | | String filepath = path + "/" + filename; |
| | | //OSS文件存储路径 |
| | | String ossPath = "contract/" + filename; |
| | | |
| | | //服务器端保存的文件对象 |
| | | File serverFile = new File(filepath); |
| | | if(!serverFile.exists()) { |
| | | try { |
| | | //创建文件 |
| | | serverFile.createNewFile(); |
| | | //将上传的文件写入到服务器端文件内 |
| | | file.transferTo(serverFile); |
| | | |
| | | //上传至OSS |
| | | ossService.uploadFile(ossPath, serverFile); |
| | | contract.setFilepath(ossPath); |
| | | contractService.updateById(contract); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/download/auth") |
| | | @ManagerAuth |
| | | public ResponseEntity<InputStreamResource> download(@RequestParam("id") Integer id) { |
| | | Contract contract = contractService.selectById(id); |
| | | if (contract == null) { |
| | | return null; |
| | | } |
| | | if (Cools.isEmpty(contract.getFilepath())) { |
| | | return null; |
| | | } |
| | | |
| | | try { |
| | | return ossService.downloadFile(contract.getFilepath());//从OSS中下载文件 |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/export/auth") |
| | | @ManagerAuth |
| | | public R export(@RequestBody JSONObject param){ |
| | | EntityWrapper<Contract> wrapper = new EntityWrapper<>(); |
| | | List<String> fields = JSONObject.parseArray(param.getJSONArray("fields").toJSONString(), String.class); |
| | | Map<String, Object> map = excludeTrash(param.getJSONObject("contract")); |
| | | convert(map, wrapper); |
| | | List<Contract> list = contractService.selectList(wrapper); |
| | | return R.ok(exportSupport(list, fields)); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractQuery/auth") |
| | | @ManagerAuth |
| | | public R query(String condition) { |
| | | EntityWrapper<Contract> wrapper = new EntityWrapper<>(); |
| | | wrapper.like("id", condition); |
| | | Page<Contract> page = contractService.selectPage(new Page<>(0, 10), wrapper); |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (Contract contract : page.getRecords()){ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("id", contract.getId()); |
| | | map.put("value", contract.getId()); |
| | | result.add(map); |
| | | } |
| | | return R.ok(result); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contract/check/column/auth") |
| | | @ManagerAuth |
| | | public R query(@RequestBody JSONObject param) { |
| | | Wrapper<Contract> wrapper = new EntityWrapper<Contract>().eq(humpToLine(String.valueOf(param.get("key"))), param.get("val")); |
| | | if (null != contractService.selectOne(wrapper)){ |
| | | return R.parse(BaseRes.REPEAT).add(getComment(Contract.class, String.valueOf(param.get("key")))); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping("/contract/all/get/kv") |
| | | @ManagerAuth |
| | | public R getDataKV(@RequestParam(required = false) String condition) { |
| | | List<KeyValueVo> vos = new ArrayList<>(); |
| | | Wrapper<Contract> wrapper = new EntityWrapper<Contract>().andNew().like("id", condition).orderBy("create_time", false); |
| | | contractService.selectPage(new Page<>(1, 30), wrapper).getRecords().forEach(item -> vos.add(new KeyValueVo(String.valueOf(item.getId()), item.getId()))); |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.baomidou.mybatisplus.plugins.Page; |
| | | import com.core.common.DateUtils; |
| | | import com.zy.crm.manager.entity.ContractSales; |
| | | import com.zy.crm.manager.service.ContractSalesService; |
| | | import com.core.annotations.ManagerAuth; |
| | | import com.core.common.BaseRes; |
| | | import com.core.common.Cools; |
| | | import com.core.common.R; |
| | | import com.core.domain.KeyValueVo; |
| | | import com.zy.crm.common.web.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | | public class ContractSalesController extends BaseController { |
| | | |
| | | @Autowired |
| | | private ContractSalesService contractSalesService; |
| | | |
| | | @RequestMapping(value = "/contractSales/{id}/auth") |
| | | @ManagerAuth |
| | | public R get(@PathVariable("id") String id) { |
| | | return R.ok(contractSalesService.selectById(String.valueOf(id))); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSales/list/auth") |
| | | @ManagerAuth |
| | | public R list(@RequestParam(defaultValue = "1")Integer curr, |
| | | @RequestParam(defaultValue = "10")Integer limit, |
| | | @RequestParam(required = false)String orderByField, |
| | | @RequestParam(required = false)String orderByType, |
| | | @RequestParam(required = false)String condition, |
| | | @RequestParam Map<String, Object> param){ |
| | | EntityWrapper<ContractSales> wrapper = new EntityWrapper<>(); |
| | | excludeTrash(param); |
| | | convert(param, wrapper); |
| | | allLike(ContractSales.class, param.keySet(), wrapper, condition); |
| | | if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));} |
| | | return R.ok(contractSalesService.selectPage(new Page<>(curr, limit), wrapper)); |
| | | } |
| | | |
| | | private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){ |
| | | for (Map.Entry<String, Object> entry : map.entrySet()){ |
| | | String val = String.valueOf(entry.getValue()); |
| | | if (val.contains(RANGE_TIME_LINK)){ |
| | | String[] dates = val.split(RANGE_TIME_LINK); |
| | | wrapper.ge(entry.getKey(), DateUtils.convert(dates[0])); |
| | | wrapper.le(entry.getKey(), DateUtils.convert(dates[1])); |
| | | } else { |
| | | wrapper.like(entry.getKey(), val); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSales/add/auth") |
| | | @ManagerAuth |
| | | public R add(ContractSales contractSales) { |
| | | contractSalesService.insert(contractSales); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSales/update/auth") |
| | | @ManagerAuth |
| | | public R update(ContractSales contractSales){ |
| | | if (Cools.isEmpty(contractSales) || null==contractSales.getId()){ |
| | | return R.error(); |
| | | } |
| | | contractSalesService.updateById(contractSales); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSales/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | contractSalesService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSales/export/auth") |
| | | @ManagerAuth |
| | | public R export(@RequestBody JSONObject param){ |
| | | EntityWrapper<ContractSales> wrapper = new EntityWrapper<>(); |
| | | List<String> fields = JSONObject.parseArray(param.getJSONArray("fields").toJSONString(), String.class); |
| | | Map<String, Object> map = excludeTrash(param.getJSONObject("contractSales")); |
| | | convert(map, wrapper); |
| | | List<ContractSales> list = contractSalesService.selectList(wrapper); |
| | | return R.ok(exportSupport(list, fields)); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSalesQuery/auth") |
| | | @ManagerAuth |
| | | public R query(String condition) { |
| | | EntityWrapper<ContractSales> wrapper = new EntityWrapper<>(); |
| | | wrapper.like("id", condition); |
| | | Page<ContractSales> page = contractSalesService.selectPage(new Page<>(0, 10), wrapper); |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (ContractSales contractSales : page.getRecords()){ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("id", contractSales.getId()); |
| | | map.put("value", contractSales.getId()); |
| | | result.add(map); |
| | | } |
| | | return R.ok(result); |
| | | } |
| | | |
| | | @RequestMapping(value = "/contractSales/check/column/auth") |
| | | @ManagerAuth |
| | | public R query(@RequestBody JSONObject param) { |
| | | Wrapper<ContractSales> wrapper = new EntityWrapper<ContractSales>().eq(humpToLine(String.valueOf(param.get("key"))), param.get("val")); |
| | | if (null != contractSalesService.selectOne(wrapper)){ |
| | | return R.parse(BaseRes.REPEAT).add(getComment(ContractSales.class, String.valueOf(param.get("key")))); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping("/contractSales/all/get/kv") |
| | | @ManagerAuth |
| | | public R getDataKV(@RequestParam(required = false) String condition) { |
| | | List<KeyValueVo> vos = new ArrayList<>(); |
| | | Wrapper<ContractSales> wrapper = new EntityWrapper<ContractSales>().andNew().like("id", condition).orderBy("create_time", false); |
| | | contractSalesService.selectPage(new Page<>(1, 30), wrapper).getRecords().forEach(item -> vos.add(new KeyValueVo(String.valueOf(item.getId()), item.getId()))); |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.controller; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import org.apache.poi.xwpf.usermodel.*; |
| | | import org.apache.xmlbeans.XmlCursor; |
| | | import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge; |
| | | import org.springframework.core.io.InputStreamResource; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.io.*; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @RestController |
| | | public class WordController { |
| | | |
| | | @GetMapping("/generateWord") |
| | | public ResponseEntity<InputStreamResource> generateWord() throws IOException { |
| | | // 读取 Word 模板文件 |
| | | String fileName = this.getClass().getClassLoader().getResource("word1.docx").getPath();//获取文件路径 |
| | | File file = new File(fileName); |
| | | FileInputStream inputStream = new FileInputStream(file); |
| | | XWPFDocument document = new XWPFDocument(inputStream); |
| | | |
| | | insertTab("${table}", document); |
| | | |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("${table}", ""); |
| | | map.put("${name}", "张三"); |
| | | processParagraphs(document.getParagraphs(), map, document); |
| | | |
| | | // 将文档写入输出流 |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | document.write(outputStream); |
| | | outputStream.close(); |
| | | |
| | | // 创建响应实体,将输出流作为文件内容返回 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); |
| | | headers.setContentDispositionFormData("attachment", "output.docx"); |
| | | InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(outputStream.toByteArray())); |
| | | return ResponseEntity.ok() |
| | | .headers(headers) |
| | | .body(resource); |
| | | } |
| | | |
| | | /** |
| | | * 处理段落中文本,替换文本中定义的变量; |
| | | * @param paragraphList 段落列表 |
| | | * @param param 需要替换的变量及变量值 |
| | | * @param doc 需要替换的DOC |
| | | */ |
| | | public static void processParagraphs(List<XWPFParagraph> paragraphList, HashMap<String, Object> param, XWPFDocument doc) { |
| | | if (paragraphList != null && paragraphList.size() > 0) { |
| | | for (XWPFParagraph paragraph : paragraphList) { |
| | | List<XWPFRun> runs = paragraph.getRuns(); |
| | | for (XWPFRun run : runs) { |
| | | String text = run.getText(0); |
| | | if (text != null) { |
| | | boolean isSetText = false; |
| | | for (Map.Entry<String, Object> entry : param.entrySet()) { |
| | | String key = entry.getKey(); |
| | | if (text.indexOf(key) != -1) { |
| | | isSetText = true; |
| | | Object value = entry.getValue(); |
| | | if (value instanceof String) {// 文本替换 |
| | | text = text.replace(key, value.toString()); |
| | | } |
| | | } |
| | | } |
| | | if (isSetText) { |
| | | run.setText(text, 0); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 在定位的位置插入表格 |
| | | */ |
| | | public static void insertTab(String key, XWPFDocument doc2) { |
| | | List<XWPFParagraph> paragraphList = doc2.getParagraphs(); |
| | | if (paragraphList != null && paragraphList.size() > 0) { |
| | | for (XWPFParagraph paragraph : paragraphList) { |
| | | List<XWPFRun> runs = paragraph.getRuns(); |
| | | for (XWPFRun run : runs) { |
| | | String text = run.getText(0); |
| | | if (text != null) { |
| | | if (text.indexOf(key) >= 0) { |
| | | XmlCursor cursor = paragraph.getCTP().newCursor(); |
| | | XWPFTable tableOne = doc2.insertNewTbl(cursor);// ---这个是关键 |
| | | String test = "[\n" + |
| | | " [\"序号\",\"品名\",\"数量\",\"单位\",\"单价(元)\",\"合计(元)\",\"备注\"],\n" + |
| | | " [\"1\",\"自动化立体仓库设备\",\"1\",\"套\",\"130000\",\"130000\",\"备注\"],\n" + |
| | | " [\"合计(大写金额):\",\"\",\"\",\"\",\"合计:\",\"\",\"\"]\n" + |
| | | "]"; |
| | | |
| | | JSONArray row = JSON.parseArray(test); |
| | | ArrayList<List<String>> list = new ArrayList<>(); |
| | | for (Object o : row) { |
| | | ArrayList<String> arrayList = new ArrayList<>(); |
| | | JSONArray objects = JSON.parseArray(o.toString()); |
| | | for (Object object : objects) { |
| | | arrayList.add(object.toString()); |
| | | } |
| | | list.add(arrayList); |
| | | } |
| | | |
| | | int rows = list.size(); |
| | | int cols = list.get(0).size(); |
| | | for (int i = 0; i < rows; i++) { |
| | | XWPFTableRow tableRow = null; |
| | | if (i == 0) { |
| | | tableRow = tableOne.getRow(i); |
| | | }else { |
| | | tableRow = tableOne.createRow(); |
| | | } |
| | | |
| | | for (int j = 0; j < cols; j++) { |
| | | if (i == 0 && j == 0) { |
| | | tableRow.getCell(j).setText(list.get(i).get(j)); |
| | | }else { |
| | | XWPFTableCell cell = tableRow.getCell(j); |
| | | if (cell == null) { |
| | | tableRow.addNewTableCell().setText(list.get(i).get(j)); |
| | | }else { |
| | | cell.setText(list.get(i).get(j)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //合并最后一行单元格 |
| | | tableOne.getRow(rows - 1).getCell(0).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART); |
| | | tableOne.getRow(rows - 1).getCell(1).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); |
| | | tableOne.getRow(rows - 1).getCell(2).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); |
| | | tableOne.getRow(rows - 1).getCell(4).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART); |
| | | tableOne.getRow(rows - 1).getCell(5).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.entity; |
| | | |
| | | import com.core.common.Cools;import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import com.baomidou.mybatisplus.annotations.TableField; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import com.core.common.SpringUtils; |
| | | import com.zy.crm.system.entity.User; |
| | | import com.zy.crm.system.service.UserService; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @TableName("man_contract") |
| | | public class Contract implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value= "") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 甲方 |
| | | */ |
| | | @ApiModelProperty(value= "甲方") |
| | | private String customer; |
| | | |
| | | /** |
| | | * 甲方地址 |
| | | */ |
| | | @ApiModelProperty(value= "甲方地址") |
| | | private String address; |
| | | |
| | | /** |
| | | * 公司名称 |
| | | */ |
| | | @ApiModelProperty(value= "公司名称") |
| | | private String company; |
| | | |
| | | /** |
| | | * 公司地址 |
| | | */ |
| | | @ApiModelProperty(value= "公司地址") |
| | | @TableField("company_address") |
| | | private String companyAddress; |
| | | |
| | | /** |
| | | * 公司税号 |
| | | */ |
| | | @ApiModelProperty(value= "公司税号") |
| | | @TableField("tax_num") |
| | | private String taxNum; |
| | | |
| | | /** |
| | | * 开户银行 |
| | | */ |
| | | @ApiModelProperty(value= "开户银行") |
| | | private String bank; |
| | | |
| | | /** |
| | | * 银行账号 |
| | | */ |
| | | @ApiModelProperty(value= "银行账号") |
| | | @TableField("bank_num") |
| | | private String bankNum; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | @ApiModelProperty(value= "创建时间") |
| | | @TableField("create_time") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | */ |
| | | @ApiModelProperty(value= "更新时间") |
| | | @TableField("update_time") |
| | | @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 创建人员 |
| | | */ |
| | | @ApiModelProperty(value= "创建人员") |
| | | @TableField("create_by") |
| | | private Long createBy; |
| | | |
| | | /** |
| | | * 更新人员 |
| | | */ |
| | | @ApiModelProperty(value= "更新人员") |
| | | @TableField("update_by") |
| | | private Long updateBy; |
| | | |
| | | /** |
| | | * 上传合同地址 |
| | | */ |
| | | @ApiModelProperty(value= "上传合同地址") |
| | | private String filepath; |
| | | |
| | | /** |
| | | * 城市 |
| | | */ |
| | | @ApiModelProperty(value= "城市") |
| | | private String city; |
| | | |
| | | /** |
| | | * 收货地址 |
| | | */ |
| | | @ApiModelProperty(value= "收货地址") |
| | | @TableField("shipping_address") |
| | | private String shippingAddress; |
| | | |
| | | /** |
| | | * 收货人 |
| | | */ |
| | | @ApiModelProperty(value= "收货人") |
| | | @TableField("shipping_name") |
| | | private String shippingName; |
| | | |
| | | /** |
| | | * 收货人电话 |
| | | */ |
| | | @ApiModelProperty(value= "收货人电话") |
| | | @TableField("shipping_phone") |
| | | private String shippingPhone; |
| | | |
| | | /** |
| | | * 合同总金额 |
| | | */ |
| | | @ApiModelProperty(value= "合同总金额") |
| | | private Double price; |
| | | |
| | | /** |
| | | * 电子邮箱 |
| | | */ |
| | | @ApiModelProperty(value= "电子邮箱") |
| | | private String email; |
| | | |
| | | /** |
| | | * 合同名称 |
| | | */ |
| | | @ApiModelProperty(value= "合同名称") |
| | | private String name; |
| | | |
| | | /** |
| | | * 合同状态{1:正常,0:禁止} |
| | | */ |
| | | @ApiModelProperty(value= "合同状态{1:正常,0:禁止}") |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 备注 |
| | | */ |
| | | @ApiModelProperty(value= "备注") |
| | | private String memo; |
| | | |
| | | /** |
| | | * 法人或授权代表 |
| | | */ |
| | | @ApiModelProperty(value= "法人或授权代表") |
| | | private String boss; |
| | | |
| | | public Contract() {} |
| | | |
| | | public Contract(Long id, String customer, String address, String company, String companyAddress, String taxNum, String bank, String bankNum, Date createTime, Date updateTime, Long createBy, Long updateBy, String filepath, String city, String shippingAddress, String shippingName, String shippingPhone, Double price, String email, String name, Integer status, String memo, String boss) { |
| | | this.id = id; |
| | | this.customer = customer; |
| | | this.address = address; |
| | | this.company = company; |
| | | this.companyAddress = companyAddress; |
| | | this.taxNum = taxNum; |
| | | this.bank = bank; |
| | | this.bankNum = bankNum; |
| | | this.createTime = createTime; |
| | | this.updateTime = updateTime; |
| | | this.createBy = createBy; |
| | | this.updateBy = updateBy; |
| | | this.filepath = filepath; |
| | | this.city = city; |
| | | this.shippingAddress = shippingAddress; |
| | | this.shippingName = shippingName; |
| | | this.shippingPhone = shippingPhone; |
| | | this.price = price; |
| | | this.email = email; |
| | | this.name = name; |
| | | this.status = status; |
| | | this.memo = memo; |
| | | this.boss = boss; |
| | | } |
| | | |
| | | // Contract contract = new Contract( |
| | | // null, // [非空] |
| | | // null, // 甲方 |
| | | // null, // 甲方地址 |
| | | // null, // 公司名称 |
| | | // null, // 公司地址 |
| | | // null, // 公司税号 |
| | | // null, // 开户银行 |
| | | // null, // 银行账号 |
| | | // null, // 创建时间 |
| | | // null, // 更新时间 |
| | | // null, // 创建人员 |
| | | // null, // 更新人员 |
| | | // null, // 上传合同地址 |
| | | // null, // 城市 |
| | | // null, // 收货地址 |
| | | // null, // 收货人 |
| | | // null, // 收货人电话 |
| | | // null, // 合同总金额 |
| | | // null // 电子邮箱 |
| | | // ); |
| | | |
| | | public String getCreateTime$(){ |
| | | if (Cools.isEmpty(this.createTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime); |
| | | } |
| | | |
| | | public String getUpdateTime$(){ |
| | | if (Cools.isEmpty(this.updateTime)){ |
| | | return ""; |
| | | } |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime); |
| | | } |
| | | |
| | | public String getCreateBy$() { |
| | | UserService userService = SpringUtils.getBean(UserService.class); |
| | | User user = userService.selectById(this.createBy); |
| | | if (!Cools.isEmpty(user)){ |
| | | return String.valueOf(user.getNickname()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public String getUpdateBy$() { |
| | | UserService userService = SpringUtils.getBean(UserService.class); |
| | | User user = userService.selectById(this.updateBy); |
| | | if (!Cools.isEmpty(user)){ |
| | | return String.valueOf(user.getNickname()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public String getStatus$() { |
| | | if (null == this.status){ return null; } |
| | | switch (this.status){ |
| | | case 1: |
| | | return "正常"; |
| | | case 0: |
| | | return "禁用"; |
| | | default: |
| | | return String.valueOf(this.status); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.entity; |
| | | |
| | | import com.core.common.Cools;import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import com.baomidou.mybatisplus.annotations.TableField; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @TableName("man_contract_sales") |
| | | public class ContractSales implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value= "") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 品名 |
| | | */ |
| | | @ApiModelProperty(value= "品名") |
| | | private String name; |
| | | |
| | | /** |
| | | * 数量 |
| | | */ |
| | | @ApiModelProperty(value= "数量") |
| | | private Double num; |
| | | |
| | | /** |
| | | * 单位 |
| | | */ |
| | | @ApiModelProperty(value= "单位") |
| | | private String unit; |
| | | |
| | | /** |
| | | * 单价 |
| | | */ |
| | | @ApiModelProperty(value= "单价") |
| | | @TableField("unit_price") |
| | | private Double unitPrice; |
| | | |
| | | /** |
| | | * 总价 |
| | | */ |
| | | @ApiModelProperty(value= "总价") |
| | | @TableField("total_price") |
| | | private Double totalPrice; |
| | | |
| | | /** |
| | | * 备注 |
| | | */ |
| | | @ApiModelProperty(value= "备注") |
| | | private String memo; |
| | | |
| | | /** |
| | | * 合同ID |
| | | */ |
| | | @ApiModelProperty(value= "合同ID") |
| | | private Long contractId; |
| | | |
| | | public ContractSales() {} |
| | | |
| | | public ContractSales(Long id, String name, Double num, String unit, Double unitPrice, Double totalPrice, String memo, Long contractId) { |
| | | this.id = id; |
| | | this.name = name; |
| | | this.num = num; |
| | | this.unit = unit; |
| | | this.unitPrice = unitPrice; |
| | | this.totalPrice = totalPrice; |
| | | this.memo = memo; |
| | | this.contractId = contractId; |
| | | } |
| | | |
| | | // ContractSales contractSales = new ContractSales( |
| | | // null, // 品名 |
| | | // null, // 数量 |
| | | // null, // 单位 |
| | | // null, // 单价 |
| | | // null, // 总价 |
| | | // null // 备注 |
| | | // ); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.mapper; |
| | | |
| | | import com.zy.crm.manager.entity.Contract; |
| | | import com.baomidou.mybatisplus.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface ContractMapper extends BaseMapper<Contract> { |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.mapper; |
| | | |
| | | import com.zy.crm.manager.entity.ContractSales; |
| | | import com.baomidou.mybatisplus.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface ContractSalesMapper extends BaseMapper<ContractSales> { |
| | | |
| | | List<ContractSales> selectByContractId(Long contractId); |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.service; |
| | | |
| | | import com.zy.crm.manager.entity.ContractSales; |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface ContractSalesService extends IService<ContractSales> { |
| | | |
| | | List<ContractSales> selectByContractId(Long contractId); |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.service; |
| | | |
| | | import com.zy.crm.manager.entity.Contract; |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | |
| | | public interface ContractService extends IService<Contract> { |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.service.impl; |
| | | |
| | | import com.zy.crm.manager.mapper.ContractSalesMapper; |
| | | import com.zy.crm.manager.entity.ContractSales; |
| | | import com.zy.crm.manager.service.ContractSalesService; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Service("contractSalesService") |
| | | public class ContractSalesServiceImpl extends ServiceImpl<ContractSalesMapper, ContractSales> implements ContractSalesService { |
| | | |
| | | @Override |
| | | public List<ContractSales> selectByContractId(Long contractId) { |
| | | return this.baseMapper.selectByContractId(contractId); |
| | | } |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.service.impl; |
| | | |
| | | import com.zy.crm.manager.mapper.ContractMapper; |
| | | import com.zy.crm.manager.entity.Contract; |
| | | import com.zy.crm.manager.service.ContractService; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("contractService") |
| | | public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService { |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.utils; |
| | | |
| | | //数字中文大写工具类 |
| | | public class ChineseNumberUtils { |
| | | |
| | | private static final String[] CN_NUMERIC = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}; |
| | | |
| | | private static final String[] CN_CARRY = {"", "拾", "佰", "仟"}; |
| | | |
| | | private static final String[] CN_UNITS = {"", "万", "亿", "兆"}; |
| | | |
| | | private static final String CN_FULL = "整"; |
| | | |
| | | private static final String CN_NEGATIVE = "负"; |
| | | |
| | | public static String numberToChinese(double number) { |
| | | if (number == 0) { |
| | | return CN_NUMERIC[0]; |
| | | } |
| | | |
| | | long temp = (long) (number * 100); |
| | | int numFen = (int) (temp % 10); |
| | | temp = temp / 10; |
| | | int numJiao = (int) (temp % 10); |
| | | temp = temp / 10; |
| | | int[] parts = new int[20]; |
| | | int numParts = 0; |
| | | for (int i = 0; temp != 0; i++) { |
| | | int partNum = (int) (temp % 10000); |
| | | parts[i] = partNum; |
| | | temp = temp / 10000; |
| | | numParts++; |
| | | } |
| | | |
| | | boolean lastIsZero = true; |
| | | String chineseStr = ""; |
| | | for (int i = 0; i < numParts; i++) { |
| | | if (parts[i] == 0) { |
| | | lastIsZero = true; |
| | | if (i == numParts - 1) { |
| | | chineseStr = CN_UNITS[i] + chineseStr; |
| | | } |
| | | continue; |
| | | } |
| | | if (lastIsZero) { |
| | | chineseStr = CN_NUMERIC[0] + chineseStr; |
| | | } |
| | | String partChinese = partTranslate(parts[i]); |
| | | partChinese += CN_UNITS[i]; |
| | | chineseStr = partChinese + chineseStr; |
| | | lastIsZero = false; |
| | | } |
| | | |
| | | if (numFen == 0 && numJiao == 0) { |
| | | chineseStr += CN_FULL; |
| | | } else if (numFen == 0) { |
| | | chineseStr += CN_NUMERIC[numJiao] + "角" + CN_FULL; |
| | | } else { |
| | | if (lastIsZero) { |
| | | chineseStr += CN_NUMERIC[0]; |
| | | } |
| | | chineseStr += CN_NUMERIC[numJiao] + "角" + CN_NUMERIC[numFen] + "分"; |
| | | } |
| | | |
| | | return chineseStr; |
| | | } |
| | | |
| | | private static String partTranslate(int partNum) { |
| | | if (partNum < 0 || partNum > 10000) { |
| | | return ""; |
| | | } |
| | | |
| | | String[] chNum = new String[4]; |
| | | int unitPos = 0; |
| | | boolean zero = true; |
| | | while (partNum > 0) { |
| | | int num = partNum % 10; |
| | | if (num == 0) { |
| | | if (!zero) { |
| | | zero = true; |
| | | chNum[unitPos++] = CN_NUMERIC[num]; |
| | | } |
| | | } else { |
| | | zero = false; |
| | | chNum[unitPos++] = CN_NUMERIC[num] + CN_CARRY[unitPos - 1]; |
| | | } |
| | | partNum = partNum / 10; |
| | | } |
| | | |
| | | StringBuilder strBuf = new StringBuilder(); |
| | | boolean hasValue = false; |
| | | for (int i = 0; i < 4; i++) { |
| | | if (chNum[i] != null) { |
| | | if (i > 0 && !hasValue) { |
| | | strBuf.insert(0, CN_NUMERIC[0]); |
| | | } |
| | | strBuf.insert(0, chNum[i]); |
| | | hasValue = true; |
| | | } |
| | | } |
| | | |
| | | return strBuf.toString(); |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | double number = 123456789.23; |
| | | String chineseNumber = numberToChinese(number); |
| | | System.out.println(chineseNumber); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.crm.manager.utils; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import org.apache.poi.xwpf.usermodel.*; |
| | | import org.apache.xmlbeans.XmlCursor; |
| | | import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge; |
| | | import org.springframework.core.io.InputStreamResource; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.ResponseEntity; |
| | | |
| | | import java.io.*; |
| | | import java.text.DecimalFormat; |
| | | import java.text.NumberFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | //Word操作工具类 |
| | | public class WordUtils { |
| | | |
| | | //生成word合同 |
| | | public static ResponseEntity<InputStreamResource> generate(String fileName, HashMap<String, Object> map, List<List<String>> tabParam) throws IOException { |
| | | // 读取 Word 模板文件 |
| | | File file = new File(fileName); |
| | | FileInputStream inputStream = new FileInputStream(file); |
| | | XWPFDocument document = new XWPFDocument(inputStream); |
| | | |
| | | insertTab("{{table}}", document, tabParam); |
| | | |
| | | map.put("{{table}}", ""); |
| | | processParagraphs(map, document); |
| | | |
| | | // 将文档写入输出流 |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | document.write(outputStream); |
| | | outputStream.close(); |
| | | |
| | | // 创建响应实体,将输出流作为文件内容返回 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); |
| | | headers.setContentDispositionFormData("attachment", "output.docx"); |
| | | InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(outputStream.toByteArray())); |
| | | return ResponseEntity.ok() |
| | | .headers(headers) |
| | | .body(resource); |
| | | } |
| | | |
| | | /** |
| | | * 处理段落中文本,替换文本中定义的变量; |
| | | * @param param 需要替换的变量及变量值 |
| | | * @param document 需要替换的DOC |
| | | */ |
| | | public static void processParagraphs(HashMap<String, Object> param, XWPFDocument document) { |
| | | // 遍历所有段落 |
| | | for (XWPFParagraph paragraph : document.getParagraphs()) { |
| | | for (Map.Entry<String, Object> entry : param.entrySet()) { |
| | | String key = entry.getKey(); |
| | | String value = entry.getValue().toString(); |
| | | // 替换段落文本 |
| | | replaceTextInParagraph(paragraph, key, value); |
| | | } |
| | | } |
| | | |
| | | // 遍历所有表格 |
| | | for (XWPFTable table : document.getTables()) { |
| | | // 遍历表格中的每个单元格 |
| | | for (XWPFTableRow row : table.getRows()) { |
| | | for (XWPFTableCell cell : row.getTableCells()) { |
| | | for (Map.Entry<String, Object> entry : param.entrySet()) { |
| | | String key = entry.getKey(); |
| | | String value = entry.getValue().toString(); |
| | | // 替换表格单元格的文本 |
| | | replaceTextInParagraph(cell.getParagraphs().get(0), key, value); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void replaceTextInParagraph(XWPFParagraph paragraph, String searchString, String replacementString) { |
| | | for (XWPFRun run : paragraph.getRuns()) { |
| | | // 获取段落中的文本 |
| | | String text = run.getText(0); |
| | | if (text != null && text.contains(searchString)) { |
| | | // 使用正则表达式进行替换 |
| | | Pattern pattern = Pattern.compile(Pattern.quote(searchString)); |
| | | Matcher matcher = pattern.matcher(text); |
| | | if (matcher.find()) { |
| | | String replacedText = matcher.replaceAll(replacementString); |
| | | // 替换文本 |
| | | run.setText(replacedText, 0); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 在定位的位置插入表格 |
| | | */ |
| | | public static void insertTab(String key, XWPFDocument document, List<List<String>> param) { |
| | | List<XWPFParagraph> paragraphList = document.getParagraphs(); |
| | | if (paragraphList != null && paragraphList.size() > 0) { |
| | | for (XWPFParagraph paragraph : paragraphList) { |
| | | List<XWPFRun> runs = paragraph.getRuns(); |
| | | for (XWPFRun run : runs) { |
| | | String text = run.getText(0); |
| | | if (text != null) { |
| | | if (text.indexOf(key) >= 0) { |
| | | XmlCursor cursor = paragraph.getCTP().newCursor(); |
| | | XWPFTable tableOne = document.insertNewTbl(cursor);// ---这个是关键 |
| | | // String test = "[\n" + |
| | | // " [\"序号\",\"品名\",\"数量\",\"单位\",\"单价(元)\",\"合计(元)\",\"备注\"],\n" + |
| | | // " [\"1\",\"自动化立体仓库设备\",\"1\",\"套\",\"130000\",\"130000\",\"备注\"],\n" + |
| | | // " [\"合计(大写金额):\",\"\",\"\",\"\",\"合计:\",\"\",\"\"]\n" + |
| | | // "]"; |
| | | // |
| | | // JSONArray row = JSON.parseArray(test); |
| | | // ArrayList<List<String>> list = new ArrayList<>(); |
| | | // for (Object o : row) { |
| | | // ArrayList<String> arrayList = new ArrayList<>(); |
| | | // JSONArray objects = JSON.parseArray(o.toString()); |
| | | // for (Object object : objects) { |
| | | // arrayList.add(object.toString()); |
| | | // } |
| | | // list.add(arrayList); |
| | | // } |
| | | |
| | | int rows = param.size(); |
| | | int cols = param.get(0).size(); |
| | | for (int i = 0; i < rows; i++) { |
| | | XWPFTableRow tableRow = null; |
| | | if (i == 0) { |
| | | tableRow = tableOne.getRow(i); |
| | | } else { |
| | | tableRow = tableOne.createRow(); |
| | | } |
| | | |
| | | for (int j = 0; j < cols; j++) { |
| | | if (i == 0 && j == 0) { |
| | | tableRow.getCell(j).setText(param.get(i).get(j)); |
| | | } else { |
| | | XWPFTableCell cell = tableRow.getCell(j); |
| | | if (cell == null) { |
| | | tableRow.addNewTableCell().setText(param.get(i).get(j)); |
| | | } else { |
| | | cell.setText(param.get(i).get(j)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //合并最后一行单元格 |
| | | tableOne.getRow(rows - 1).getCell(0).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART); |
| | | tableOne.getRow(rows - 1).getCell(1).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); |
| | | tableOne.getRow(rows - 1).getCell(2).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); |
| | | tableOne.getRow(rows - 1).getCell(4).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART); |
| | | tableOne.getRow(rows - 1).getCell(5).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static String formatNumberForAccounting(double number) { |
| | | NumberFormat formatter = new DecimalFormat("#,###.00"); |
| | | return formatter.format(number); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.zy.crm.manager.mapper.ContractMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.zy.crm.manager.entity.Contract"> |
| | | <result column="id" property="id" /> |
| | | <result column="customer" property="customer" /> |
| | | <result column="address" property="address" /> |
| | | <result column="company" property="company" /> |
| | | <result column="company_address" property="companyAddress" /> |
| | | <result column="tax_num" property="taxNum" /> |
| | | <result column="bank" property="bank" /> |
| | | <result column="bank_num" property="bankNum" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="filepath" property="filepath" /> |
| | | <result column="city" property="city" /> |
| | | <result column="shipping_address" property="shippingAddress" /> |
| | | <result column="shipping_name" property="shippingName" /> |
| | | <result column="shipping_phone" property="shippingPhone" /> |
| | | <result column="price" property="price" /> |
| | | <result column="email" property="email" /> |
| | | <result column="name" property="name" /> |
| | | <result column="status" property="status" /> |
| | | <result column="memo" property="memo" /> |
| | | <result column="boss" property="boss" /> |
| | | |
| | | </resultMap> |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.zy.crm.manager.mapper.ContractSalesMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.zy.crm.manager.entity.ContractSales"> |
| | | <id column="id" property="id" /> |
| | | <result column="name" property="name" /> |
| | | <result column="num" property="num" /> |
| | | <result column="unit" property="unit" /> |
| | | <result column="unit_price" property="unitPrice" /> |
| | | <result column="total_price" property="totalPrice" /> |
| | | <result column="memo" property="memo" /> |
| | | <result column="contract_id" property="contractId" /> |
| | | |
| | | </resultMap> |
| | | |
| | | <select id="selectByContractId" resultMap="BaseResultMap"> |
| | | select * from man_contract_sales |
| | | where contract_id = #{contractId} |
| | | </select> |
| | | |
| | | </mapper> |
New file |
| | |
| | | var pageCurr; |
| | | layui.config({ |
| | | base: baseUrl + "/static/layui/lay/modules/" |
| | | }).use(['table','laydate', 'form', 'admin'], function(){ |
| | | var table = layui.table; |
| | | var $ = layui.jquery; |
| | | var layer = layui.layer; |
| | | var layDate = layui.laydate; |
| | | var form = layui.form; |
| | | var admin = layui.admin; |
| | | |
| | | // 数据渲染 |
| | | tableIns = table.render({ |
| | | elem: '#contract', |
| | | headers: {token: localStorage.getItem('token')}, |
| | | url: baseUrl+'/contract/list/auth', |
| | | page: true, |
| | | limit: 15, |
| | | limits: [15, 30, 50, 100, 200, 500], |
| | | toolbar: '#toolbar', |
| | | cellMinWidth: 50, |
| | | height: 'full-120', |
| | | cols: [[ |
| | | {type: 'checkbox'} |
| | | ,{field: 'id', align: 'center',title: '#ID'} |
| | | ,{field: 'name', align: 'center',title: '合同名称'} |
| | | ,{field: 'customer', align: 'center',title: '甲方'} |
| | | ,{field: 'company', align: 'center',title: '公司名称'} |
| | | ,{field: 'status$', align: 'center',title: '状态'} |
| | | ,{field: 'createBy$', align: 'center',title: '添加人员'} |
| | | ,{field: 'createTime$', align: 'center',title: '添加时间'} |
| | | ,{field: 'updateBy$', align: 'center',title: '修改人员'} |
| | | ,{field: 'updateTime$', align: 'center',title: '修改时间'} |
| | | ,{field: 'memo', align: 'center',title: '备注'} |
| | | |
| | | ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:400} |
| | | ]], |
| | | request: { |
| | | pageName: 'curr', |
| | | pageSize: 'limit' |
| | | }, |
| | | parseData: function (res) { |
| | | return { |
| | | 'code': res.code, |
| | | 'msg': res.msg, |
| | | 'count': res.data.total, |
| | | 'data': res.data.records |
| | | } |
| | | }, |
| | | response: { |
| | | statusCode: 200 |
| | | }, |
| | | done: function(res, curr, count) { |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl+"/"; |
| | | } |
| | | pageCurr=curr; |
| | | limit(); |
| | | } |
| | | }); |
| | | |
| | | // 监听排序事件 |
| | | table.on('sort(contract)', function (obj) { |
| | | var searchData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | searchData[this.name] = this.value; |
| | | }); |
| | | searchData['orderByField'] = obj.field; |
| | | searchData['orderByType'] = obj.type; |
| | | tableIns.reload({ |
| | | where: searchData, |
| | | page: {curr: 1} |
| | | }); |
| | | }); |
| | | |
| | | // 监听头工具栏事件 |
| | | table.on('toolbar(contract)', function (obj) { |
| | | var checkStatus = table.checkStatus(obj.config.id).data; |
| | | switch(obj.event) { |
| | | case 'addData': |
| | | showEditModel(); |
| | | break; |
| | | case 'deleteData': |
| | | if (checkStatus.length === 0) { |
| | | layer.msg('请选择要删除的数据', {icon: 2}); |
| | | return; |
| | | } |
| | | del(checkStatus.map(function (d) { |
| | | return d.id; |
| | | })); |
| | | break; |
| | | case 'exportData': |
| | | admin.confirm('确定导出Excel吗', {shadeClose: true}, function(){ |
| | | var titles=[]; |
| | | var fields=[]; |
| | | obj.config.cols[0].map(function (col) { |
| | | if (col.type === 'normal' && col.hide === false && col.toolbar == null) { |
| | | titles.push(col.title); |
| | | fields.push(col.field); |
| | | } |
| | | }); |
| | | var exportData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | exportData[this.name] = this.value; |
| | | }); |
| | | var param = { |
| | | 'contract': exportData, |
| | | 'fields': fields |
| | | }; |
| | | $.ajax({ |
| | | url: baseUrl+"/contract/export/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: JSON.stringify(param), |
| | | dataType:'json', |
| | | contentType:'application/json;charset=UTF-8', |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.closeAll(); |
| | | if (res.code === 200) { |
| | | table.exportFile(titles,res.data,'xls'); |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl+"/"; |
| | | } else { |
| | | layer.msg(res.msg, {icon: 2}) |
| | | } |
| | | } |
| | | }); |
| | | }); |
| | | break; |
| | | } |
| | | }); |
| | | |
| | | // 监听行工具事件 |
| | | table.on('tool(contract)', function(obj){ |
| | | var data = obj.data; |
| | | switch (obj.event) { |
| | | case 'edit': |
| | | showEditModel(data); |
| | | break; |
| | | case "del": |
| | | del([data.id]); |
| | | break; |
| | | case "generate": |
| | | //生成合同 |
| | | generate(data) |
| | | break |
| | | case "sales": |
| | | //合同明细 |
| | | sales(data); |
| | | break |
| | | case "upload": |
| | | //上传合同 |
| | | upload(data) |
| | | break |
| | | case "download": |
| | | //下载合同 |
| | | download(data) |
| | | break |
| | | } |
| | | }); |
| | | |
| | | /* 弹窗 - 新增、修改 */ |
| | | function showEditModel(mData) { |
| | | admin.open({ |
| | | type: 1, |
| | | area: '800px', |
| | | title: (mData ? '修改' : '添加') + '合同', |
| | | content: $('#editDialog').html(), |
| | | success: function (layero, dIndex) { |
| | | layDateRender(mData); |
| | | form.val('detail', mData); |
| | | form.on('submit(editSubmit)', function (data) { |
| | | var loadIndex = layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl+"/contract/"+(mData?'update':'add')+"/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: data.field, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.close(loadIndex); |
| | | if (res.code === 200){ |
| | | layer.close(dIndex); |
| | | layer.msg(res.msg, {icon: 1}); |
| | | tableReload(); |
| | | } else if (res.code === 403){ |
| | | top.location.href = baseUrl+"/"; |
| | | }else { |
| | | layer.msg(res.msg, {icon: 2}); |
| | | } |
| | | } |
| | | }) |
| | | return false; |
| | | }); |
| | | $(layero).children('.layui-layer-content').css('overflow', 'visible'); |
| | | layui.form.render('select'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /* 生成合同 */ |
| | | function generate(mData) { |
| | | admin.open({ |
| | | type: 1, |
| | | area: '600px', |
| | | title: '生成合同', |
| | | content: $('#generateDialog').html(), |
| | | success: function (layero, dIndex) { |
| | | layDateRender(mData); |
| | | form.val('detail', mData); |
| | | form.on('submit(generateSubmit)', function (data) { |
| | | var loadIndex = layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl + "/contract/generate/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: data.field, |
| | | method: 'GET', |
| | | xhrFields: { |
| | | responseType: "blob" // 设置响应类型为二进制数据 |
| | | }, |
| | | success: function (res) { |
| | | // 创建一个临时的下载链接 |
| | | const url = window.URL.createObjectURL(res); |
| | | // 创建一个隐藏的 <a> 元素并设置下载链接 |
| | | const a = document.createElement("a"); |
| | | a.style.display = "none"; |
| | | a.href = url; |
| | | a.download = data.field.name + ".docx"; // 指定下载的文件名 |
| | | document.body.appendChild(a); |
| | | |
| | | // 触发点击事件以开始下载 |
| | | a.click(); |
| | | |
| | | // 清理临时资源 |
| | | setTimeout(function() { |
| | | window.URL.revokeObjectURL(url); |
| | | document.body.removeChild(a); |
| | | }, 100); |
| | | |
| | | layer.close(loadIndex); |
| | | layer.close(dIndex); |
| | | } |
| | | }) |
| | | return false; |
| | | }); |
| | | $(layero).children('.layui-layer-content').css('overflow', 'visible'); |
| | | layui.form.render('select'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /* 合同明细 */ |
| | | function sales(mData) { |
| | | layer.open({ |
| | | type: 2, |
| | | title: '合同明细', |
| | | maxmin: true, |
| | | area: [top.detailWidth,top.detailHeight], |
| | | shadeClose: false, |
| | | content: '../contractSales/contractSales.html?contractId=' + mData.id, |
| | | success: function(layero, index){ |
| | | } |
| | | }); |
| | | } |
| | | |
| | | //上传合同 |
| | | function upload(data) { |
| | | if (data.filepath == '' || data.filepath == null) { |
| | | layer.confirm('是否上传合同?', function(){ |
| | | $("#uploadQuote").click() |
| | | }); |
| | | }else { |
| | | layer.confirm('已上传合同,是否继续覆盖上传?', function(){ |
| | | $("#uploadQuote").click() |
| | | }); |
| | | } |
| | | |
| | | $("#uploadQuote").on("change",(evt) => { |
| | | var files = evt.target.files; |
| | | if(files==null || files.length==0){ |
| | | alert("No files wait for import"); |
| | | return; |
| | | } |
| | | |
| | | let name = files[0].name; |
| | | let suffixArr = name.split("."), suffix = suffixArr[suffixArr.length-1]; |
| | | // if(suffix!="xlsx"){ |
| | | // alert("Currently only supports the import of xlsx files"); |
| | | // return; |
| | | // } |
| | | |
| | | let formData = new FormData($("#uploadFile")[0]); |
| | | formData.append("id", data.id); |
| | | $.ajax({ |
| | | url: baseUrl + "/contract/upload/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: formData, |
| | | method: 'POST', |
| | | cache: false, |
| | | processData: false, |
| | | contentType: false, |
| | | success: function (res) { |
| | | if (res.code == 200) { |
| | | layer.msg('上传成功',{time:1000},() => { |
| | | parent.location.reload() |
| | | }) |
| | | }else{ |
| | | layer.msg(res.msg,{time:1000},() => { |
| | | parent.location.reload() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | //下载合同 |
| | | function download(data) { |
| | | $.ajax({ |
| | | url: baseUrl+"/contract/download/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: data, |
| | | method: 'GET', |
| | | xhrFields: { |
| | | responseType: "blob" // 设置响应类型为二进制数据 |
| | | }, |
| | | success: function (res) { |
| | | // 创建一个临时的下载链接 |
| | | const url = window.URL.createObjectURL(res); |
| | | // 创建一个隐藏的 <a> 元素并设置下载链接 |
| | | const a = document.createElement("a"); |
| | | a.style.display = "none"; |
| | | a.href = url; |
| | | |
| | | let list = data.filepath.split(".") |
| | | let suffix = "." + list[list.length - 1]//获取后缀名 |
| | | a.download = data.name + suffix; // 指定下载的文件名 |
| | | document.body.appendChild(a); |
| | | |
| | | // 触发点击事件以开始下载 |
| | | a.click(); |
| | | |
| | | // 清理临时资源 |
| | | setTimeout(function() { |
| | | window.URL.revokeObjectURL(url); |
| | | document.body.removeChild(a); |
| | | }, 100); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /* 删除 */ |
| | | function del(ids) { |
| | | layer.confirm('确定要删除选中数据吗?', { |
| | | skin: 'layui-layer-admin', |
| | | shade: .1 |
| | | }, function (i) { |
| | | layer.close(i); |
| | | var loadIndex = layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl+"/contract/delete/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: {ids: ids}, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.close(loadIndex); |
| | | if (res.code === 200){ |
| | | layer.msg(res.msg, {icon: 1}); |
| | | tableReload(); |
| | | } else if (res.code === 403){ |
| | | top.location.href = baseUrl+"/"; |
| | | } else { |
| | | layer.msg(res.msg, {icon: 2}); |
| | | } |
| | | } |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // 搜索 |
| | | form.on('submit(search)', function (data) { |
| | | pageCurr = 1; |
| | | tableReload(false); |
| | | }); |
| | | |
| | | // 重置 |
| | | form.on('submit(reset)', function (data) { |
| | | pageCurr = 1; |
| | | clearFormVal($('#search-box')); |
| | | tableReload(false); |
| | | }); |
| | | |
| | | // 时间选择器 |
| | | function layDateRender(data) { |
| | | setTimeout(function () { |
| | | layDate.render({ |
| | | elem: '.layui-laydate-range' |
| | | ,type: 'datetime' |
| | | ,range: true |
| | | }); |
| | | layDate.render({ |
| | | elem: '#createTime\\$', |
| | | type: 'datetime', |
| | | value: data!==undefined?data['createTime\\$']:null |
| | | }); |
| | | layDate.render({ |
| | | elem: '#updateTime\\$', |
| | | type: 'datetime', |
| | | value: data!==undefined?data['updateTime\\$']:null |
| | | }); |
| | | |
| | | }, 300); |
| | | } |
| | | layDateRender(); |
| | | |
| | | }); |
| | | |
| | | // 关闭动作 |
| | | $(document).on('click','#data-detail-close', function () { |
| | | parent.layer.closeAll(); |
| | | }); |
| | | |
| | | function tableReload(child) { |
| | | var searchData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | searchData[this.name] = this.value; |
| | | }); |
| | | tableIns.reload({ |
| | | where: searchData, |
| | | page: {curr: pageCurr} |
| | | }); |
| | | } |
New file |
| | |
| | | var pageCurr; |
| | | var pageCount = 0; |
| | | layui.config({ |
| | | base: baseUrl + "/static/layui/lay/modules/" |
| | | }).use(['table','laydate', 'form', 'admin', 'xmSelect'], function(){ |
| | | var table = layui.table; |
| | | var $ = layui.jquery; |
| | | var layer = layui.layer; |
| | | var layDate = layui.laydate; |
| | | var form = layui.form; |
| | | var admin = layui.admin; |
| | | var xmSelect = layui.xmSelect; |
| | | |
| | | var contractId = getQueryVariable("contractId") |
| | | if (contractId != false) { |
| | | $("#contract_id").val(contractId) |
| | | } |
| | | |
| | | // 数据渲染 |
| | | tableIns = table.render({ |
| | | elem: '#contractSales', |
| | | headers: {token: localStorage.getItem('token')}, |
| | | url: baseUrl+'/contractSales/list/auth', |
| | | page: true, |
| | | limit: 15, |
| | | limits: [15, 30, 50, 100, 200, 500], |
| | | toolbar: '#toolbar', |
| | | cellMinWidth: 50, |
| | | height: 'full-120', |
| | | where: {contract_id: $('#contract_id').val()}, |
| | | cols: [[ |
| | | {type: 'checkbox'} |
| | | // ,{field: 'id', align: 'center',title: ''} |
| | | ,{field: 'name', align: 'center',title: '品名'} |
| | | ,{field: 'num', align: 'center',title: '数量'} |
| | | ,{field: 'unit', align: 'center',title: '单位'} |
| | | ,{field: 'unitPrice', align: 'center',title: '单价'} |
| | | ,{field: 'totalPrice', align: 'center',title: '总价'} |
| | | ,{field: 'memo', align: 'center',title: '备注'} |
| | | |
| | | ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:120} |
| | | ]], |
| | | request: { |
| | | pageName: 'curr', |
| | | pageSize: 'limit' |
| | | }, |
| | | parseData: function (res) { |
| | | return { |
| | | 'code': res.code, |
| | | 'msg': res.msg, |
| | | 'count': res.data.total, |
| | | 'data': res.data.records |
| | | } |
| | | }, |
| | | response: { |
| | | statusCode: 200 |
| | | }, |
| | | done: function(res, curr, count) { |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl+"/"; |
| | | } |
| | | pageCurr=curr;pageCount=count; |
| | | limit(); |
| | | } |
| | | }); |
| | | |
| | | // 监听排序事件 |
| | | table.on('sort(contractSales)', function (obj) { |
| | | var searchData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | searchData[this.name] = this.value; |
| | | }); |
| | | searchData['orderByField'] = obj.field; |
| | | searchData['orderByType'] = obj.type; |
| | | tableIns.reload({ |
| | | where: searchData, |
| | | page: {curr: 1} |
| | | }); |
| | | }); |
| | | |
| | | // 监听头工具栏事件 |
| | | table.on('toolbar(contractSales)', function (obj) { |
| | | var checkStatus = table.checkStatus(obj.config.id).data; |
| | | switch(obj.event) { |
| | | case 'addData': |
| | | showEditModel(); |
| | | break; |
| | | case 'deleteData': |
| | | if (checkStatus.length === 0) { |
| | | layer.msg('请选择要删除的数据', {icon: 2}); |
| | | return; |
| | | } |
| | | del(checkStatus.map(function (d) { |
| | | return d.id; |
| | | })); |
| | | break; |
| | | case 'exportData': |
| | | admin.confirm('确定导出Excel吗', {shadeClose: true}, function(){ |
| | | var titles=[]; |
| | | var fields=[]; |
| | | obj.config.cols[0].map(function (col) { |
| | | if (col.type === 'normal' && col.hide === false && col.toolbar == null) { |
| | | titles.push(col.title); |
| | | fields.push(col.field); |
| | | } |
| | | }); |
| | | var exportData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | exportData[this.name] = this.value; |
| | | }); |
| | | var param = { |
| | | 'contractSales': exportData, |
| | | 'fields': fields |
| | | }; |
| | | $.ajax({ |
| | | url: baseUrl+"/contractSales/export/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: JSON.stringify(param), |
| | | dataType:'json', |
| | | contentType:'application/json;charset=UTF-8', |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.closeAll(); |
| | | if (res.code === 200) { |
| | | table.exportFile(titles,res.data,'xls'); |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl+"/"; |
| | | } else { |
| | | layer.msg(res.msg, {icon: 2}) |
| | | } |
| | | } |
| | | }); |
| | | }); |
| | | break; |
| | | } |
| | | }); |
| | | |
| | | // 监听行工具事件 |
| | | table.on('tool(contractSales)', function(obj){ |
| | | var data = obj.data; |
| | | switch (obj.event) { |
| | | case 'edit': |
| | | showEditModel(data); |
| | | break; |
| | | case "del": |
| | | del([data.id]); |
| | | break; |
| | | } |
| | | }); |
| | | |
| | | /* 弹窗 - 新增、修改 */ |
| | | function showEditModel(mData) { |
| | | admin.open({ |
| | | type: 1, |
| | | area: '600px', |
| | | title: (mData ? '修改' : '添加') + '', |
| | | content: $('#editDialog').html(), |
| | | success: function (layero, dIndex) { |
| | | layDateRender(mData); |
| | | form.val('detail', mData); |
| | | form.on('submit(editSubmit)', function (data) { |
| | | var loadIndex = layer.load(2); |
| | | data.field.contractId = $("#contract_id").val() |
| | | $.ajax({ |
| | | url: baseUrl+"/contractSales/"+(mData?'update':'add')+"/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: data.field, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.close(loadIndex); |
| | | if (res.code === 200){ |
| | | layer.close(dIndex); |
| | | layer.msg(res.msg, {icon: 1}); |
| | | tableReload(); |
| | | } else if (res.code === 403){ |
| | | top.location.href = baseUrl+"/"; |
| | | }else { |
| | | layer.msg(res.msg, {icon: 2}); |
| | | } |
| | | } |
| | | }) |
| | | return false; |
| | | }); |
| | | $(layero).children('.layui-layer-content').css('overflow', 'visible'); |
| | | layui.form.render('select'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /* 删除 */ |
| | | function del(ids) { |
| | | layer.confirm('确定要删除选中数据吗?', { |
| | | skin: 'layui-layer-admin', |
| | | shade: .1 |
| | | }, function (i) { |
| | | layer.close(i); |
| | | var loadIndex = layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl+"/contractSales/delete/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: {ids: ids}, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.close(loadIndex); |
| | | if (res.code === 200){ |
| | | layer.msg(res.msg, {icon: 1}); |
| | | tableReload(); |
| | | } else if (res.code === 403){ |
| | | top.location.href = baseUrl+"/"; |
| | | } else { |
| | | layer.msg(res.msg, {icon: 2}); |
| | | } |
| | | } |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // 搜索 |
| | | form.on('submit(search)', function (data) { |
| | | pageCurr = 1; |
| | | tableReload(); |
| | | }); |
| | | |
| | | // 重置 |
| | | form.on('submit(reset)', function (data) { |
| | | pageCurr = 1; |
| | | clearFormVal($('#search-box')); |
| | | tableReload(); |
| | | }); |
| | | |
| | | // 时间选择器 |
| | | function layDateRender(data) { |
| | | setTimeout(function () { |
| | | layDate.render({ |
| | | elem: '.layui-laydate-range' |
| | | ,type: 'datetime' |
| | | ,range: true |
| | | }); |
| | | |
| | | }, 300); |
| | | } |
| | | layDateRender(); |
| | | |
| | | |
| | | |
| | | }); |
| | | |
| | | // 关闭动作 |
| | | $(document).on('click','#data-detail-close', function () { |
| | | parent.layer.closeAll(); |
| | | }); |
| | | |
| | | function tableReload() { |
| | | var searchData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | searchData[this.name] = this.value; |
| | | }); |
| | | tableIns.reload({ |
| | | where: searchData, |
| | | page: {curr: pageCurr} |
| | | }); |
| | | } |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <title></title> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
| | | <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all"> |
| | | <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all"> |
| | | <link rel="stylesheet" href="../../static/css/cool.css" media="all"> |
| | | </head> |
| | | <body> |
| | | |
| | | <div class="layui-fluid"> |
| | | <div class="layui-card"> |
| | | <div class="layui-card-body"> |
| | | <div class="layui-form toolbar" id="search-box"> |
| | | <div class="layui-form-item"> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline" style="width: 300px"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input layui-laydate-range" name="create_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="condition" placeholder="请输入" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline">  |
| | | <button class="layui-btn icon-btn" lay-filter="search" lay-submit> |
| | | <i class="layui-icon"></i>搜索 |
| | | </button> |
| | | <button class="layui-btn icon-btn" lay-filter="reset" lay-submit> |
| | | <i class="layui-icon"></i>重置 |
| | | </button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <table class="layui-hide" id="contract" lay-filter="contract"></table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <form id="uploadFile" enctype="multipart/form-data" style="display: none;" > |
| | | <input type="file" name="file" id="uploadQuote"> |
| | | <input type="button" onclick="upload()" value="上传"/> |
| | | </form> |
| | | |
| | | <script type="text/html" id="toolbar"> |
| | | <div class="layui-btn-container"> |
| | | <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button> |
| | | <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">删除</button> |
| | | <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">导出</button> |
| | | </div> |
| | | </script> |
| | | |
| | | <script type="text/html" id="operate"> |
| | | <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a> |
| | | <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="sales">合同明细</a> |
| | | <a class="layui-btn layui-btn-xs btn-edit" lay-event="generate">生成合同</a> |
| | | <a class="layui-btn layui-btn-xs btn-edit" lay-event="upload">上传合同</a> |
| | | <a class="layui-btn layui-btn-xs btn-edit" lay-event="download">下载</a> |
| | | <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a> |
| | | </script> |
| | | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/contract/contract.js" charset="utf-8"></script> |
| | | </body> |
| | | <!-- 表单弹窗 --> |
| | | <script type="text/html" id="editDialog"> |
| | | <div id="detail" lay-filter="detail" class="layui-form admin-form model-form"> |
| | | <input name="id" type="hidden"> |
| | | <div class="layui-row"> |
| | | <div class="layui-col-md6"> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">合同名称: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="name" placeholder="请输入合同名称" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">甲方: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="customer" placeholder="请输入甲方" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">法人或授权代表: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="boss" placeholder="请输入法人或授权代表" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">甲方地址: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="address" placeholder="请输入甲方地址" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">公司名称: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="company" placeholder="请输入公司名称" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">公司地址: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="companyAddress" placeholder="请输入公司地址" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">公司税号: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="taxNum" placeholder="请输入公司税号" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">收货人: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="shippingName" placeholder="请输入收货人" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">收货人电话: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="shippingPhone" placeholder="请输入收货人电话" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | <div class="layui-col-md6"> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">开户银行: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="bank" placeholder="请输入开户银行" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">银行账号: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="bankNum" placeholder="请输入银行账号" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">收货地址:</label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="shippingAddress" placeholder="请输入收货地址" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">合同总金额: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="price" placeholder="请输入合同总金额" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">电子邮箱: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="email" placeholder="请输入电子邮箱"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">城市: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="city" placeholder="请输入城市"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">合同状态: </label> |
| | | <div class="layui-input-block"> |
| | | <select name="status" lay-vertype="tips" lay-verify="required"> |
| | | <option value="">请选择状态</option> |
| | | <option value="1">正常</option> |
| | | <option value="0">禁止</option> |
| | | </select> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">备注: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="memo" placeholder="请输入备注"> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | </div> |
| | | <hr class="layui-bg-gray"> |
| | | <div class="layui-form-item text-right"> |
| | | <button class="layui-btn" lay-filter="editSubmit" lay-submit="">保存</button> |
| | | <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button> |
| | | </div> |
| | | </div> |
| | | </script> |
| | | |
| | | <!-- 表单弹窗 --> |
| | | <script type="text/html" id="generateDialog"> |
| | | <div id="detail1" lay-filter="detail" class="layui-form admin-form model-form"> |
| | | <input name="id" type="hidden"> |
| | | <div class="layui-row"> |
| | | <div class="layui-col-md12"> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">合同名称: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="name" placeholder="请输入合同名称" disabled lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">合同模板: </label> |
| | | <div class="layui-input-block"> |
| | | <input type="radio" name="contractTemplate" value="jcxm_1" title="集成项目销售合同模板" checked> |
| | | <input type="radio" name="contractTemplate" value="zjxm_1" title="载具销售合同模板"> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | <hr class="layui-bg-gray"> |
| | | <div class="layui-form-item text-right"> |
| | | <button class="layui-btn" lay-filter="generateSubmit" lay-submit="">生成</button> |
| | | <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button> |
| | | </div> |
| | | </div> |
| | | </script> |
| | | </html> |
| | | |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <title></title> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
| | | <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all"> |
| | | <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all"> |
| | | <link rel="stylesheet" href="../../static/css/cool.css" media="all"> |
| | | </head> |
| | | <body> |
| | | |
| | | <div class="layui-fluid"> |
| | | <div class="layui-card"> |
| | | <div class="layui-card-body"> |
| | | <div class="layui-form toolbar" id="search-box"> |
| | | <div class="layui-form-item"> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="contract_id" id="contract_id" placeholder="合同ID" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline" style="width: 300px"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input layui-laydate-range" name="create_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="condition" placeholder="请输入" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline">  |
| | | <button class="layui-btn icon-btn" lay-filter="search" lay-submit> |
| | | <i class="layui-icon"></i>搜索 |
| | | </button> |
| | | <button class="layui-btn icon-btn" lay-filter="reset" lay-submit> |
| | | <i class="layui-icon"></i>重置 |
| | | </button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <table class="layui-hide" id="contractSales" lay-filter="contractSales"></table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <script type="text/html" id="toolbar"> |
| | | <div class="layui-btn-container"> |
| | | <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button> |
| | | <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">删除</button> |
| | | <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">导出</button> |
| | | </div> |
| | | </script> |
| | | |
| | | <script type="text/html" id="operate"> |
| | | <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a> |
| | | <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a> |
| | | </script> |
| | | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/contractSales/contractSales.js" charset="utf-8"></script> |
| | | </body> |
| | | <!-- 表单弹窗 --> |
| | | <script type="text/html" id="editDialog"> |
| | | <div id="detail" lay-filter="detail" class="layui-form admin-form model-form"> |
| | | <input name="id" type="hidden"> |
| | | <div class="layui-row"> |
| | | <div class="layui-col-md12"> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">品名: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="name" placeholder="请输入品名"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">数量: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="num" placeholder="请输入数量"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">单位: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="unit" placeholder="请输入单位"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">单价: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="unitPrice" placeholder="请输入单价"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">总价: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="totalPrice" placeholder="请输入总价"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">备注: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="memo" placeholder="请输入备注"> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | <hr class="layui-bg-gray"> |
| | | <div class="layui-form-item text-right"> |
| | | <button class="layui-btn" lay-filter="editSubmit" lay-submit="">保存</button> |
| | | <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button> |
| | | </div> |
| | | </div> |
| | | </script> |
| | | </html> |
| | | |