Here's the Gurobi code to solve the optimization problem:

```python
import gurobipy as gp

# Create a new model
m = gp.Model("resource_allocation")

# Create variables
cbrn = m.addVar(vtype=gp.GRB.INTEGER, name="CBRN_platoons")
artillery = m.addVar(vtype=gp.GRB.INTEGER, name="artillery_batteries")
water = m.addVar(vtype=gp.GRB.INTEGER, name="water_purification_units")
medical = m.addVar(vtype=gp.GRB.INTEGER, name="medical_platoons")

# Set objective function
m.setObjective(4*cbrn**2 + 7*cbrn*artillery + 9*cbrn*water + 7*cbrn*medical + 3*artillery**2 + 2*artillery*water + 8*artillery*medical + 5*water*medical + 5*medical**2 + 3*cbrn + 1*water, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(3*cbrn + 2*artillery + 5*water + 7*medical <= 117, "logistics_footprint") # Total logistics footprint constraint
m.addConstr(6*cbrn + 1*artillery + 6*water + 6*medical <= 107, "fun_factor") # Total fun factor constraint

m.addConstr(5*water + 7*medical >= 17, "water_medical_logistics_min")
m.addConstr((3*cbrn)**2 + (5*water)**2 >= 23, "cbrn_water_logistics_min_sq")
m.addConstr(3*cbrn + 2*artillery >= 11, "cbrn_artillery_logistics_min")
m.addConstr(2*artillery + 5*water >= 19, "artillery_water_logistics_min")
m.addConstr(3*cbrn + 2*artillery + 5*water + 7*medical >= 19, "total_logistics_min")

m.addConstr(6*cbrn + 1*artillery >= 14, "cbrn_artillery_fun_min")
m.addConstr(6*water + 6*medical >= 20, "water_medical_fun_min")
m.addConstr(6*cbrn + 1*artillery + 6*water + 6*medical >= 20, "total_fun_min")

m.addConstr(3*cbrn + 2*artillery <= 106, "cbrn_artillery_logistics_max")
m.addConstr((2*artillery)**2 + (7*medical)**2 <= 97, "artillery_medical_logistics_max_sq")
m.addConstr((2*artillery)**2 + (5*water)**2 <= 59, "artillery_water_logistics_max_sq")
m.addConstr(3*cbrn + 5*water + 7*medical <= 101, "cbrn_water_medical_logistics_max")


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('\nCost: %g' % m.objVal)
    print('\nSolution:')
    for v in m.getVars():
        print('%s %g' % (v.varName, v.x))
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print("Optimization ended with status %d" % m.status)

```
